@oh-my-pi/pi-coding-agent 0.1.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/CHANGELOG.md +1629 -0
- package/README.md +1041 -0
- package/docs/compaction.md +403 -0
- package/docs/config-usage.md +113 -0
- package/docs/custom-tools.md +541 -0
- package/docs/extension-loading.md +1004 -0
- package/docs/hooks.md +867 -0
- package/docs/rpc.md +1040 -0
- package/docs/sdk.md +994 -0
- package/docs/session-tree-plan.md +441 -0
- package/docs/session.md +240 -0
- package/docs/skills.md +290 -0
- package/docs/theme.md +670 -0
- package/docs/tree.md +197 -0
- package/docs/tui.md +341 -0
- package/examples/README.md +21 -0
- package/examples/custom-tools/README.md +124 -0
- package/examples/custom-tools/hello/index.ts +20 -0
- package/examples/custom-tools/question/index.ts +84 -0
- package/examples/custom-tools/subagent/README.md +172 -0
- package/examples/custom-tools/subagent/agents/planner.md +37 -0
- package/examples/custom-tools/subagent/agents/scout.md +50 -0
- package/examples/custom-tools/subagent/agents/worker.md +24 -0
- package/examples/custom-tools/subagent/agents.ts +156 -0
- package/examples/custom-tools/subagent/commands/implement-and-review.md +10 -0
- package/examples/custom-tools/subagent/commands/implement.md +10 -0
- package/examples/custom-tools/subagent/commands/scout-and-plan.md +9 -0
- package/examples/custom-tools/subagent/index.ts +1002 -0
- package/examples/custom-tools/todo/index.ts +212 -0
- package/examples/hooks/README.md +56 -0
- package/examples/hooks/auto-commit-on-exit.ts +49 -0
- package/examples/hooks/confirm-destructive.ts +59 -0
- package/examples/hooks/custom-compaction.ts +116 -0
- package/examples/hooks/dirty-repo-guard.ts +52 -0
- package/examples/hooks/file-trigger.ts +41 -0
- package/examples/hooks/git-checkpoint.ts +53 -0
- package/examples/hooks/handoff.ts +150 -0
- package/examples/hooks/permission-gate.ts +34 -0
- package/examples/hooks/protected-paths.ts +30 -0
- package/examples/hooks/qna.ts +119 -0
- package/examples/hooks/snake.ts +343 -0
- package/examples/hooks/status-line.ts +40 -0
- package/examples/sdk/01-minimal.ts +22 -0
- package/examples/sdk/02-custom-model.ts +49 -0
- package/examples/sdk/03-custom-prompt.ts +44 -0
- package/examples/sdk/04-skills.ts +44 -0
- package/examples/sdk/05-tools.ts +90 -0
- package/examples/sdk/06-hooks.ts +61 -0
- package/examples/sdk/07-context-files.ts +36 -0
- package/examples/sdk/08-slash-commands.ts +42 -0
- package/examples/sdk/09-api-keys-and-oauth.ts +55 -0
- package/examples/sdk/10-settings.ts +38 -0
- package/examples/sdk/11-sessions.ts +48 -0
- package/examples/sdk/12-full-control.ts +95 -0
- package/examples/sdk/README.md +154 -0
- package/package.json +89 -0
- package/src/bun-imports.d.ts +16 -0
- package/src/capability/context-file.ts +40 -0
- package/src/capability/extension.ts +48 -0
- package/src/capability/hook.ts +40 -0
- package/src/capability/index.ts +616 -0
- package/src/capability/instruction.ts +37 -0
- package/src/capability/mcp.ts +52 -0
- package/src/capability/prompt.ts +35 -0
- package/src/capability/rule.ts +56 -0
- package/src/capability/settings.ts +35 -0
- package/src/capability/skill.ts +49 -0
- package/src/capability/slash-command.ts +40 -0
- package/src/capability/system-prompt.ts +35 -0
- package/src/capability/tool.ts +38 -0
- package/src/capability/types.ts +166 -0
- package/src/cli/args.ts +259 -0
- package/src/cli/file-processor.ts +121 -0
- package/src/cli/list-models.ts +104 -0
- package/src/cli/plugin-cli.ts +661 -0
- package/src/cli/session-picker.ts +41 -0
- package/src/cli/update-cli.ts +274 -0
- package/src/cli.ts +10 -0
- package/src/config.ts +391 -0
- package/src/core/agent-session.ts +2178 -0
- package/src/core/auth-storage.ts +258 -0
- package/src/core/bash-executor.ts +197 -0
- package/src/core/compaction/branch-summarization.ts +315 -0
- package/src/core/compaction/compaction.ts +664 -0
- package/src/core/compaction/index.ts +7 -0
- package/src/core/compaction/utils.ts +153 -0
- package/src/core/custom-commands/bundled/review/index.ts +156 -0
- package/src/core/custom-commands/index.ts +15 -0
- package/src/core/custom-commands/loader.ts +226 -0
- package/src/core/custom-commands/types.ts +112 -0
- package/src/core/custom-tools/index.ts +22 -0
- package/src/core/custom-tools/loader.ts +248 -0
- package/src/core/custom-tools/types.ts +185 -0
- package/src/core/custom-tools/wrapper.ts +29 -0
- package/src/core/exec.ts +139 -0
- package/src/core/export-html/index.ts +159 -0
- package/src/core/export-html/template.css +774 -0
- package/src/core/export-html/template.generated.ts +2 -0
- package/src/core/export-html/template.html +45 -0
- package/src/core/export-html/template.js +1185 -0
- package/src/core/export-html/template.macro.ts +24 -0
- package/src/core/file-mentions.ts +54 -0
- package/src/core/hooks/index.ts +16 -0
- package/src/core/hooks/loader.ts +288 -0
- package/src/core/hooks/runner.ts +434 -0
- package/src/core/hooks/tool-wrapper.ts +98 -0
- package/src/core/hooks/types.ts +770 -0
- package/src/core/index.ts +53 -0
- package/src/core/logger.ts +112 -0
- package/src/core/mcp/client.ts +185 -0
- package/src/core/mcp/config.ts +248 -0
- package/src/core/mcp/index.ts +45 -0
- package/src/core/mcp/loader.ts +99 -0
- package/src/core/mcp/manager.ts +235 -0
- package/src/core/mcp/tool-bridge.ts +156 -0
- package/src/core/mcp/transports/http.ts +316 -0
- package/src/core/mcp/transports/index.ts +6 -0
- package/src/core/mcp/transports/stdio.ts +252 -0
- package/src/core/mcp/types.ts +228 -0
- package/src/core/messages.ts +211 -0
- package/src/core/model-registry.ts +334 -0
- package/src/core/model-resolver.ts +494 -0
- package/src/core/plugins/doctor.ts +67 -0
- package/src/core/plugins/index.ts +38 -0
- package/src/core/plugins/installer.ts +189 -0
- package/src/core/plugins/loader.ts +339 -0
- package/src/core/plugins/manager.ts +672 -0
- package/src/core/plugins/parser.ts +105 -0
- package/src/core/plugins/paths.ts +37 -0
- package/src/core/plugins/types.ts +190 -0
- package/src/core/sdk.ts +900 -0
- package/src/core/session-manager.ts +1837 -0
- package/src/core/settings-manager.ts +860 -0
- package/src/core/skills.ts +352 -0
- package/src/core/slash-commands.ts +132 -0
- package/src/core/system-prompt.ts +442 -0
- package/src/core/timings.ts +25 -0
- package/src/core/title-generator.ts +110 -0
- package/src/core/tools/ask.ts +193 -0
- package/src/core/tools/bash-interceptor.ts +120 -0
- package/src/core/tools/bash.ts +91 -0
- package/src/core/tools/context.ts +32 -0
- package/src/core/tools/edit-diff.ts +487 -0
- package/src/core/tools/edit.ts +140 -0
- package/src/core/tools/exa/company.ts +59 -0
- package/src/core/tools/exa/index.ts +63 -0
- package/src/core/tools/exa/linkedin.ts +59 -0
- package/src/core/tools/exa/mcp-client.ts +368 -0
- package/src/core/tools/exa/render.ts +200 -0
- package/src/core/tools/exa/researcher.ts +90 -0
- package/src/core/tools/exa/search.ts +338 -0
- package/src/core/tools/exa/types.ts +167 -0
- package/src/core/tools/exa/websets.ts +248 -0
- package/src/core/tools/find.ts +244 -0
- package/src/core/tools/grep.ts +584 -0
- package/src/core/tools/index.ts +283 -0
- package/src/core/tools/ls.ts +142 -0
- package/src/core/tools/lsp/client.ts +767 -0
- package/src/core/tools/lsp/clients/biome-client.ts +207 -0
- package/src/core/tools/lsp/clients/index.ts +49 -0
- package/src/core/tools/lsp/clients/lsp-linter-client.ts +98 -0
- package/src/core/tools/lsp/config.ts +845 -0
- package/src/core/tools/lsp/edits.ts +110 -0
- package/src/core/tools/lsp/index.ts +1364 -0
- package/src/core/tools/lsp/render.ts +560 -0
- package/src/core/tools/lsp/rust-analyzer.ts +145 -0
- package/src/core/tools/lsp/types.ts +495 -0
- package/src/core/tools/lsp/utils.ts +526 -0
- package/src/core/tools/notebook.ts +182 -0
- package/src/core/tools/output.ts +198 -0
- package/src/core/tools/path-utils.ts +61 -0
- package/src/core/tools/read.ts +507 -0
- package/src/core/tools/renderers.ts +820 -0
- package/src/core/tools/review.ts +275 -0
- package/src/core/tools/rulebook.ts +124 -0
- package/src/core/tools/task/agents.ts +158 -0
- package/src/core/tools/task/artifacts.ts +114 -0
- package/src/core/tools/task/commands.ts +157 -0
- package/src/core/tools/task/discovery.ts +217 -0
- package/src/core/tools/task/executor.ts +531 -0
- package/src/core/tools/task/index.ts +548 -0
- package/src/core/tools/task/model-resolver.ts +176 -0
- package/src/core/tools/task/parallel.ts +38 -0
- package/src/core/tools/task/render.ts +502 -0
- package/src/core/tools/task/subprocess-tool-registry.ts +89 -0
- package/src/core/tools/task/types.ts +142 -0
- package/src/core/tools/truncate.ts +265 -0
- package/src/core/tools/web-fetch.ts +2511 -0
- package/src/core/tools/web-search/auth.ts +199 -0
- package/src/core/tools/web-search/index.ts +583 -0
- package/src/core/tools/web-search/providers/anthropic.ts +198 -0
- package/src/core/tools/web-search/providers/exa.ts +196 -0
- package/src/core/tools/web-search/providers/perplexity.ts +195 -0
- package/src/core/tools/web-search/render.ts +372 -0
- package/src/core/tools/web-search/types.ts +180 -0
- package/src/core/tools/write.ts +63 -0
- package/src/core/ttsr.ts +211 -0
- package/src/core/utils.ts +187 -0
- package/src/discovery/agents-md.ts +75 -0
- package/src/discovery/builtin.ts +647 -0
- package/src/discovery/claude.ts +623 -0
- package/src/discovery/cline.ts +104 -0
- package/src/discovery/codex.ts +571 -0
- package/src/discovery/cursor.ts +266 -0
- package/src/discovery/gemini.ts +368 -0
- package/src/discovery/github.ts +120 -0
- package/src/discovery/helpers.test.ts +127 -0
- package/src/discovery/helpers.ts +249 -0
- package/src/discovery/index.ts +84 -0
- package/src/discovery/mcp-json.ts +127 -0
- package/src/discovery/vscode.ts +99 -0
- package/src/discovery/windsurf.ts +219 -0
- package/src/index.ts +192 -0
- package/src/main.ts +507 -0
- package/src/migrations.ts +156 -0
- package/src/modes/cleanup.ts +23 -0
- package/src/modes/index.ts +48 -0
- package/src/modes/interactive/components/armin.ts +382 -0
- package/src/modes/interactive/components/assistant-message.ts +86 -0
- package/src/modes/interactive/components/bash-execution.ts +199 -0
- package/src/modes/interactive/components/bordered-loader.ts +41 -0
- package/src/modes/interactive/components/branch-summary-message.ts +42 -0
- package/src/modes/interactive/components/compaction-summary-message.ts +45 -0
- package/src/modes/interactive/components/custom-editor.ts +122 -0
- package/src/modes/interactive/components/diff.ts +147 -0
- package/src/modes/interactive/components/dynamic-border.ts +25 -0
- package/src/modes/interactive/components/extensions/extension-dashboard.ts +296 -0
- package/src/modes/interactive/components/extensions/extension-list.ts +479 -0
- package/src/modes/interactive/components/extensions/index.ts +9 -0
- package/src/modes/interactive/components/extensions/inspector-panel.ts +313 -0
- package/src/modes/interactive/components/extensions/state-manager.ts +558 -0
- package/src/modes/interactive/components/extensions/types.ts +191 -0
- package/src/modes/interactive/components/hook-editor.ts +117 -0
- package/src/modes/interactive/components/hook-input.ts +64 -0
- package/src/modes/interactive/components/hook-message.ts +96 -0
- package/src/modes/interactive/components/hook-selector.ts +91 -0
- package/src/modes/interactive/components/model-selector.ts +560 -0
- package/src/modes/interactive/components/oauth-selector.ts +136 -0
- package/src/modes/interactive/components/plugin-settings.ts +481 -0
- package/src/modes/interactive/components/queue-mode-selector.ts +56 -0
- package/src/modes/interactive/components/session-selector.ts +220 -0
- package/src/modes/interactive/components/settings-defs.ts +597 -0
- package/src/modes/interactive/components/settings-selector.ts +545 -0
- package/src/modes/interactive/components/show-images-selector.ts +45 -0
- package/src/modes/interactive/components/status-line/index.ts +4 -0
- package/src/modes/interactive/components/status-line/presets.ts +94 -0
- package/src/modes/interactive/components/status-line/segments.ts +350 -0
- package/src/modes/interactive/components/status-line/separators.ts +55 -0
- package/src/modes/interactive/components/status-line/types.ts +81 -0
- package/src/modes/interactive/components/status-line-segment-editor.ts +357 -0
- package/src/modes/interactive/components/status-line.ts +384 -0
- package/src/modes/interactive/components/theme-selector.ts +62 -0
- package/src/modes/interactive/components/thinking-selector.ts +64 -0
- package/src/modes/interactive/components/tool-execution.ts +946 -0
- package/src/modes/interactive/components/tree-selector.ts +877 -0
- package/src/modes/interactive/components/ttsr-notification.ts +82 -0
- package/src/modes/interactive/components/user-message-selector.ts +159 -0
- package/src/modes/interactive/components/user-message.ts +18 -0
- package/src/modes/interactive/components/visual-truncate.ts +50 -0
- package/src/modes/interactive/components/welcome.ts +228 -0
- package/src/modes/interactive/interactive-mode.ts +2669 -0
- package/src/modes/interactive/theme/dark.json +102 -0
- package/src/modes/interactive/theme/defaults/dark-arctic.json +111 -0
- package/src/modes/interactive/theme/defaults/dark-catppuccin.json +106 -0
- package/src/modes/interactive/theme/defaults/dark-cyberpunk.json +109 -0
- package/src/modes/interactive/theme/defaults/dark-dracula.json +105 -0
- package/src/modes/interactive/theme/defaults/dark-forest.json +103 -0
- package/src/modes/interactive/theme/defaults/dark-github.json +112 -0
- package/src/modes/interactive/theme/defaults/dark-gruvbox.json +119 -0
- package/src/modes/interactive/theme/defaults/dark-monochrome.json +101 -0
- package/src/modes/interactive/theme/defaults/dark-monokai.json +105 -0
- package/src/modes/interactive/theme/defaults/dark-nord.json +104 -0
- package/src/modes/interactive/theme/defaults/dark-ocean.json +108 -0
- package/src/modes/interactive/theme/defaults/dark-one.json +107 -0
- package/src/modes/interactive/theme/defaults/dark-retro.json +99 -0
- package/src/modes/interactive/theme/defaults/dark-rose-pine.json +95 -0
- package/src/modes/interactive/theme/defaults/dark-solarized.json +96 -0
- package/src/modes/interactive/theme/defaults/dark-sunset.json +106 -0
- package/src/modes/interactive/theme/defaults/dark-synthwave.json +102 -0
- package/src/modes/interactive/theme/defaults/dark-tokyo-night.json +108 -0
- package/src/modes/interactive/theme/defaults/index.ts +67 -0
- package/src/modes/interactive/theme/defaults/light-arctic.json +106 -0
- package/src/modes/interactive/theme/defaults/light-catppuccin.json +105 -0
- package/src/modes/interactive/theme/defaults/light-cyberpunk.json +103 -0
- package/src/modes/interactive/theme/defaults/light-forest.json +107 -0
- package/src/modes/interactive/theme/defaults/light-github.json +114 -0
- package/src/modes/interactive/theme/defaults/light-gruvbox.json +115 -0
- package/src/modes/interactive/theme/defaults/light-monochrome.json +100 -0
- package/src/modes/interactive/theme/defaults/light-ocean.json +106 -0
- package/src/modes/interactive/theme/defaults/light-one.json +105 -0
- package/src/modes/interactive/theme/defaults/light-retro.json +105 -0
- package/src/modes/interactive/theme/defaults/light-solarized.json +101 -0
- package/src/modes/interactive/theme/defaults/light-sunset.json +106 -0
- package/src/modes/interactive/theme/defaults/light-synthwave.json +105 -0
- package/src/modes/interactive/theme/defaults/light-tokyo-night.json +118 -0
- package/src/modes/interactive/theme/light.json +99 -0
- package/src/modes/interactive/theme/theme-schema.json +424 -0
- package/src/modes/interactive/theme/theme.ts +2211 -0
- package/src/modes/print-mode.ts +163 -0
- package/src/modes/rpc/rpc-client.ts +527 -0
- package/src/modes/rpc/rpc-mode.ts +494 -0
- package/src/modes/rpc/rpc-types.ts +203 -0
- package/src/prompts/architect-plan.md +10 -0
- package/src/prompts/branch-summary-preamble.md +3 -0
- package/src/prompts/branch-summary.md +28 -0
- package/src/prompts/browser.md +71 -0
- package/src/prompts/compaction-summary.md +34 -0
- package/src/prompts/compaction-turn-prefix.md +16 -0
- package/src/prompts/compaction-update-summary.md +41 -0
- package/src/prompts/explore.md +82 -0
- package/src/prompts/implement-with-critic.md +11 -0
- package/src/prompts/implement.md +11 -0
- package/src/prompts/init.md +30 -0
- package/src/prompts/plan.md +54 -0
- package/src/prompts/reviewer.md +81 -0
- package/src/prompts/summarization-system.md +3 -0
- package/src/prompts/system-prompt.md +27 -0
- package/src/prompts/task.md +56 -0
- package/src/prompts/title-system.md +8 -0
- package/src/prompts/tools/ask.md +24 -0
- package/src/prompts/tools/bash.md +23 -0
- package/src/prompts/tools/edit.md +9 -0
- package/src/prompts/tools/find.md +6 -0
- package/src/prompts/tools/grep.md +12 -0
- package/src/prompts/tools/lsp.md +14 -0
- package/src/prompts/tools/output.md +23 -0
- package/src/prompts/tools/read.md +25 -0
- package/src/prompts/tools/web-fetch.md +8 -0
- package/src/prompts/tools/web-search.md +10 -0
- package/src/prompts/tools/write.md +10 -0
- package/src/utils/changelog.ts +99 -0
- package/src/utils/clipboard.ts +265 -0
- package/src/utils/fuzzy.ts +108 -0
- package/src/utils/mime.ts +30 -0
- package/src/utils/shell-snapshot.ts +218 -0
- package/src/utils/shell.ts +364 -0
- package/src/utils/tools-manager.ts +265 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VS Code Provider
|
|
3
|
+
*
|
|
4
|
+
* Loads config from `.vscode` directory (project-only).
|
|
5
|
+
* Supports MCP server discovery from `mcp.json` with nested `mcp.servers` structure.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { registerProvider } from "../capability/index";
|
|
9
|
+
import { type MCPServer, mcpCapability } from "../capability/mcp";
|
|
10
|
+
import type { LoadContext, LoadResult } from "../capability/types";
|
|
11
|
+
import { createSourceMeta, expandEnvVarsDeep, getProjectPath, parseJSON } from "./helpers";
|
|
12
|
+
|
|
13
|
+
const PROVIDER_ID = "vscode";
|
|
14
|
+
const DISPLAY_NAME = "VS Code";
|
|
15
|
+
const PRIORITY = 20;
|
|
16
|
+
|
|
17
|
+
// =============================================================================
|
|
18
|
+
// MCP Servers
|
|
19
|
+
// =============================================================================
|
|
20
|
+
|
|
21
|
+
registerProvider<MCPServer>(mcpCapability.id, {
|
|
22
|
+
id: PROVIDER_ID,
|
|
23
|
+
displayName: DISPLAY_NAME,
|
|
24
|
+
description: "Load MCP servers from .vscode/mcp.json",
|
|
25
|
+
priority: PRIORITY,
|
|
26
|
+
load(ctx: LoadContext): LoadResult<MCPServer> {
|
|
27
|
+
const items: MCPServer[] = [];
|
|
28
|
+
const warnings: string[] = [];
|
|
29
|
+
|
|
30
|
+
// Project-only (VS Code doesn't support user-level MCP config)
|
|
31
|
+
const projectPath = getProjectPath(ctx, "vscode", "mcp.json");
|
|
32
|
+
if (projectPath && ctx.fs.isFile(projectPath)) {
|
|
33
|
+
const result = loadMCPConfig(ctx, projectPath, "project");
|
|
34
|
+
items.push(...result.items);
|
|
35
|
+
if (result.warnings) warnings.push(...result.warnings);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return { items, warnings };
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Load MCP servers from a mcp.json file.
|
|
44
|
+
* VS Code uses nested structure: { "mcp": { "servers": { ... } } }
|
|
45
|
+
*/
|
|
46
|
+
function loadMCPConfig(ctx: LoadContext, path: string, level: "user" | "project"): LoadResult<MCPServer> {
|
|
47
|
+
const items: MCPServer[] = [];
|
|
48
|
+
const warnings: string[] = [];
|
|
49
|
+
|
|
50
|
+
const content = ctx.fs.readFile(path);
|
|
51
|
+
if (!content) {
|
|
52
|
+
warnings.push(`Failed to read ${path}`);
|
|
53
|
+
return { items, warnings };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const parsed = parseJSON<{ mcp?: { servers?: Record<string, unknown> } }>(content);
|
|
57
|
+
if (!parsed) {
|
|
58
|
+
warnings.push(`Invalid JSON in ${path}`);
|
|
59
|
+
return { items, warnings };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// VS Code uses nested structure: mcp.servers
|
|
63
|
+
const servers = parsed.mcp?.servers;
|
|
64
|
+
if (!servers || typeof servers !== "object") {
|
|
65
|
+
return { items, warnings };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
for (const [name, config] of Object.entries(servers)) {
|
|
69
|
+
if (!config || typeof config !== "object") {
|
|
70
|
+
warnings.push(`Invalid config for server "${name}" in ${path}`);
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const raw = config as Record<string, unknown>;
|
|
75
|
+
|
|
76
|
+
// Expand environment variables
|
|
77
|
+
const expanded = expandEnvVarsDeep(raw);
|
|
78
|
+
|
|
79
|
+
const server: MCPServer = {
|
|
80
|
+
name,
|
|
81
|
+
command: typeof expanded.command === "string" ? expanded.command : undefined,
|
|
82
|
+
args: Array.isArray(expanded.args) ? (expanded.args as string[]) : undefined,
|
|
83
|
+
env: expanded.env && typeof expanded.env === "object" ? (expanded.env as Record<string, string>) : undefined,
|
|
84
|
+
url: typeof expanded.url === "string" ? expanded.url : undefined,
|
|
85
|
+
headers:
|
|
86
|
+
expanded.headers && typeof expanded.headers === "object"
|
|
87
|
+
? (expanded.headers as Record<string, string>)
|
|
88
|
+
: undefined,
|
|
89
|
+
transport: ["stdio", "sse", "http"].includes(expanded.transport as string)
|
|
90
|
+
? (expanded.transport as "stdio" | "sse" | "http")
|
|
91
|
+
: undefined,
|
|
92
|
+
_source: createSourceMeta(PROVIDER_ID, path, level),
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
items.push(server);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return { items, warnings };
|
|
99
|
+
}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Windsurf (Codeium) Provider
|
|
3
|
+
*
|
|
4
|
+
* Loads configuration from Windsurf's config locations:
|
|
5
|
+
* - User: ~/.codeium/windsurf
|
|
6
|
+
* - Project: .windsurf
|
|
7
|
+
*
|
|
8
|
+
* Supports:
|
|
9
|
+
* - MCP servers from mcp_config.json
|
|
10
|
+
* - Rules from .windsurf/rules/*.md and ~/.codeium/windsurf/memories/global_rules.md
|
|
11
|
+
* - Legacy .windsurfrules file
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { registerProvider } from "../capability/index";
|
|
15
|
+
import { type MCPServer, mcpCapability } from "../capability/mcp";
|
|
16
|
+
import { type Rule, ruleCapability } from "../capability/rule";
|
|
17
|
+
import type { LoadContext, LoadResult } from "../capability/types";
|
|
18
|
+
import {
|
|
19
|
+
createSourceMeta,
|
|
20
|
+
expandEnvVarsDeep,
|
|
21
|
+
getProjectPath,
|
|
22
|
+
getUserPath,
|
|
23
|
+
loadFilesFromDir,
|
|
24
|
+
parseFrontmatter,
|
|
25
|
+
parseJSON,
|
|
26
|
+
} from "./helpers";
|
|
27
|
+
|
|
28
|
+
const PROVIDER_ID = "windsurf";
|
|
29
|
+
const DISPLAY_NAME = "Windsurf";
|
|
30
|
+
const PRIORITY = 50;
|
|
31
|
+
|
|
32
|
+
// =============================================================================
|
|
33
|
+
// MCP Servers
|
|
34
|
+
// =============================================================================
|
|
35
|
+
|
|
36
|
+
function loadMCPServers(ctx: LoadContext): LoadResult<MCPServer> {
|
|
37
|
+
const items: MCPServer[] = [];
|
|
38
|
+
const warnings: string[] = [];
|
|
39
|
+
|
|
40
|
+
// User-level: ~/.codeium/windsurf/mcp_config.json
|
|
41
|
+
const userPath = getUserPath(ctx, "windsurf", "mcp_config.json");
|
|
42
|
+
if (userPath && ctx.fs.isFile(userPath)) {
|
|
43
|
+
const content = ctx.fs.readFile(userPath);
|
|
44
|
+
if (content) {
|
|
45
|
+
const config = parseJSON<{ mcpServers?: Record<string, unknown> }>(content);
|
|
46
|
+
if (config?.mcpServers) {
|
|
47
|
+
for (const [name, serverConfig] of Object.entries(config.mcpServers)) {
|
|
48
|
+
if (typeof serverConfig !== "object" || serverConfig === null) {
|
|
49
|
+
warnings.push(`Invalid server config for "${name}" in ${userPath}`);
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const server = expandEnvVarsDeep(serverConfig as Record<string, unknown>);
|
|
54
|
+
items.push({
|
|
55
|
+
name,
|
|
56
|
+
command: server.command as string | undefined,
|
|
57
|
+
args: server.args as string[] | undefined,
|
|
58
|
+
env: server.env as Record<string, string> | undefined,
|
|
59
|
+
url: server.url as string | undefined,
|
|
60
|
+
headers: server.headers as Record<string, string> | undefined,
|
|
61
|
+
transport: server.type as "stdio" | "sse" | "http" | undefined,
|
|
62
|
+
_source: createSourceMeta(PROVIDER_ID, userPath, "user"),
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Project-level: .windsurf/mcp_config.json
|
|
70
|
+
const projectPath = getProjectPath(ctx, "windsurf", "mcp_config.json");
|
|
71
|
+
if (projectPath && ctx.fs.isFile(projectPath)) {
|
|
72
|
+
const content = ctx.fs.readFile(projectPath);
|
|
73
|
+
if (content) {
|
|
74
|
+
const config = parseJSON<{ mcpServers?: Record<string, unknown> }>(content);
|
|
75
|
+
if (config?.mcpServers) {
|
|
76
|
+
for (const [name, serverConfig] of Object.entries(config.mcpServers)) {
|
|
77
|
+
if (typeof serverConfig !== "object" || serverConfig === null) {
|
|
78
|
+
warnings.push(`Invalid server config for "${name}" in ${projectPath}`);
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const server = expandEnvVarsDeep(serverConfig as Record<string, unknown>);
|
|
83
|
+
items.push({
|
|
84
|
+
name,
|
|
85
|
+
command: server.command as string | undefined,
|
|
86
|
+
args: server.args as string[] | undefined,
|
|
87
|
+
env: server.env as Record<string, string> | undefined,
|
|
88
|
+
url: server.url as string | undefined,
|
|
89
|
+
headers: server.headers as Record<string, string> | undefined,
|
|
90
|
+
transport: server.type as "stdio" | "sse" | "http" | undefined,
|
|
91
|
+
_source: createSourceMeta(PROVIDER_ID, projectPath, "project"),
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return { items, warnings };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// =============================================================================
|
|
102
|
+
// Rules
|
|
103
|
+
// =============================================================================
|
|
104
|
+
|
|
105
|
+
function loadRules(ctx: LoadContext): LoadResult<Rule> {
|
|
106
|
+
const items: Rule[] = [];
|
|
107
|
+
const warnings: string[] = [];
|
|
108
|
+
|
|
109
|
+
// User-level: ~/.codeium/windsurf/memories/global_rules.md
|
|
110
|
+
const userPath = getUserPath(ctx, "windsurf", "memories/global_rules.md");
|
|
111
|
+
if (userPath && ctx.fs.isFile(userPath)) {
|
|
112
|
+
const content = ctx.fs.readFile(userPath);
|
|
113
|
+
if (content) {
|
|
114
|
+
const { frontmatter, body } = parseFrontmatter(content);
|
|
115
|
+
|
|
116
|
+
// Validate and normalize globs
|
|
117
|
+
let globs: string[] | undefined;
|
|
118
|
+
if (Array.isArray(frontmatter.globs)) {
|
|
119
|
+
globs = frontmatter.globs.filter((g): g is string => typeof g === "string");
|
|
120
|
+
} else if (typeof frontmatter.globs === "string") {
|
|
121
|
+
globs = [frontmatter.globs];
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
items.push({
|
|
125
|
+
name: "global_rules",
|
|
126
|
+
path: userPath,
|
|
127
|
+
content: body,
|
|
128
|
+
globs,
|
|
129
|
+
alwaysApply: frontmatter.alwaysApply as boolean | undefined,
|
|
130
|
+
description: frontmatter.description as string | undefined,
|
|
131
|
+
ttsrTrigger: typeof frontmatter.ttsr_trigger === "string" ? frontmatter.ttsr_trigger : undefined,
|
|
132
|
+
_source: createSourceMeta(PROVIDER_ID, userPath, "user"),
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Project-level: .windsurf/rules/*.md
|
|
138
|
+
const projectRulesDir = getProjectPath(ctx, "windsurf", "rules");
|
|
139
|
+
if (projectRulesDir) {
|
|
140
|
+
const result = loadFilesFromDir<Rule>(ctx, projectRulesDir, PROVIDER_ID, "project", {
|
|
141
|
+
extensions: ["md"],
|
|
142
|
+
transform: (name, content, path, source) => {
|
|
143
|
+
const { frontmatter, body } = parseFrontmatter(content);
|
|
144
|
+
const ruleName = name.replace(/\.md$/, "");
|
|
145
|
+
|
|
146
|
+
// Validate and normalize globs
|
|
147
|
+
let globs: string[] | undefined;
|
|
148
|
+
if (Array.isArray(frontmatter.globs)) {
|
|
149
|
+
globs = frontmatter.globs.filter((g): g is string => typeof g === "string");
|
|
150
|
+
} else if (typeof frontmatter.globs === "string") {
|
|
151
|
+
globs = [frontmatter.globs];
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return {
|
|
155
|
+
name: ruleName,
|
|
156
|
+
path,
|
|
157
|
+
content: body,
|
|
158
|
+
globs,
|
|
159
|
+
alwaysApply: frontmatter.alwaysApply as boolean | undefined,
|
|
160
|
+
description: frontmatter.description as string | undefined,
|
|
161
|
+
ttsrTrigger: typeof frontmatter.ttsr_trigger === "string" ? frontmatter.ttsr_trigger : undefined,
|
|
162
|
+
_source: source,
|
|
163
|
+
};
|
|
164
|
+
},
|
|
165
|
+
});
|
|
166
|
+
items.push(...result.items);
|
|
167
|
+
if (result.warnings) warnings.push(...result.warnings);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Legacy: .windsurfrules in project root
|
|
171
|
+
const legacyPath = ctx.fs.walkUp(".windsurfrules", { file: true });
|
|
172
|
+
if (legacyPath) {
|
|
173
|
+
const content = ctx.fs.readFile(legacyPath);
|
|
174
|
+
if (content) {
|
|
175
|
+
const { frontmatter, body } = parseFrontmatter(content);
|
|
176
|
+
|
|
177
|
+
// Validate and normalize globs
|
|
178
|
+
let globs: string[] | undefined;
|
|
179
|
+
if (Array.isArray(frontmatter.globs)) {
|
|
180
|
+
globs = frontmatter.globs.filter((g): g is string => typeof g === "string");
|
|
181
|
+
} else if (typeof frontmatter.globs === "string") {
|
|
182
|
+
globs = [frontmatter.globs];
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
items.push({
|
|
186
|
+
name: "windsurfrules",
|
|
187
|
+
path: legacyPath,
|
|
188
|
+
content: body,
|
|
189
|
+
globs,
|
|
190
|
+
alwaysApply: frontmatter.alwaysApply as boolean | undefined,
|
|
191
|
+
description: frontmatter.description as string | undefined,
|
|
192
|
+
ttsrTrigger: typeof frontmatter.ttsr_trigger === "string" ? frontmatter.ttsr_trigger : undefined,
|
|
193
|
+
_source: createSourceMeta(PROVIDER_ID, legacyPath, "project"),
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return { items, warnings };
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// =============================================================================
|
|
202
|
+
// Provider Registration
|
|
203
|
+
// =============================================================================
|
|
204
|
+
|
|
205
|
+
registerProvider<MCPServer>(mcpCapability.id, {
|
|
206
|
+
id: PROVIDER_ID,
|
|
207
|
+
displayName: DISPLAY_NAME,
|
|
208
|
+
description: "Load MCP servers from Windsurf config (mcp_config.json)",
|
|
209
|
+
priority: PRIORITY,
|
|
210
|
+
load: loadMCPServers,
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
registerProvider<Rule>(ruleCapability.id, {
|
|
214
|
+
id: PROVIDER_ID,
|
|
215
|
+
displayName: DISPLAY_NAME,
|
|
216
|
+
description: "Load rules from Windsurf (.windsurf/rules/*.md, memories/global_rules.md, .windsurfrules)",
|
|
217
|
+
priority: PRIORITY,
|
|
218
|
+
load: loadRules,
|
|
219
|
+
});
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
// Core session management
|
|
2
|
+
|
|
3
|
+
// Re-export TUI components for custom tool rendering
|
|
4
|
+
export { Container, Markdown, Spacer, Text } from "@oh-my-pi/pi-tui";
|
|
5
|
+
export {
|
|
6
|
+
AgentSession,
|
|
7
|
+
type AgentSessionConfig,
|
|
8
|
+
type AgentSessionEvent,
|
|
9
|
+
type AgentSessionEventListener,
|
|
10
|
+
type ModelCycleResult,
|
|
11
|
+
type PromptOptions,
|
|
12
|
+
type SessionStats,
|
|
13
|
+
} from "./core/agent-session";
|
|
14
|
+
// Auth and model registry
|
|
15
|
+
export { type ApiKeyCredential, type AuthCredential, AuthStorage, type OAuthCredential } from "./core/auth-storage";
|
|
16
|
+
// Compaction
|
|
17
|
+
export {
|
|
18
|
+
type BranchPreparation,
|
|
19
|
+
type BranchSummaryResult,
|
|
20
|
+
type CollectEntriesResult,
|
|
21
|
+
type CompactionResult,
|
|
22
|
+
type CutPointResult,
|
|
23
|
+
calculateContextTokens,
|
|
24
|
+
collectEntriesForBranchSummary,
|
|
25
|
+
compact,
|
|
26
|
+
DEFAULT_COMPACTION_SETTINGS,
|
|
27
|
+
estimateTokens,
|
|
28
|
+
type FileOperations,
|
|
29
|
+
findCutPoint,
|
|
30
|
+
findTurnStartIndex,
|
|
31
|
+
type GenerateBranchSummaryOptions,
|
|
32
|
+
generateBranchSummary,
|
|
33
|
+
generateSummary,
|
|
34
|
+
getLastAssistantUsage,
|
|
35
|
+
prepareBranchEntries,
|
|
36
|
+
serializeConversation,
|
|
37
|
+
shouldCompact,
|
|
38
|
+
} from "./core/compaction/index";
|
|
39
|
+
// Custom commands
|
|
40
|
+
export type {
|
|
41
|
+
CustomCommand,
|
|
42
|
+
CustomCommandAPI,
|
|
43
|
+
CustomCommandFactory,
|
|
44
|
+
CustomCommandSource,
|
|
45
|
+
CustomCommandsLoadResult,
|
|
46
|
+
LoadedCustomCommand,
|
|
47
|
+
} from "./core/custom-commands/types";
|
|
48
|
+
// Custom tools
|
|
49
|
+
export type {
|
|
50
|
+
AgentToolUpdateCallback,
|
|
51
|
+
CustomTool,
|
|
52
|
+
CustomToolAPI,
|
|
53
|
+
CustomToolContext,
|
|
54
|
+
CustomToolFactory,
|
|
55
|
+
CustomToolSessionEvent,
|
|
56
|
+
CustomToolsLoadResult,
|
|
57
|
+
CustomToolUIContext,
|
|
58
|
+
ExecResult,
|
|
59
|
+
LoadedCustomTool,
|
|
60
|
+
RenderResultOptions,
|
|
61
|
+
} from "./core/custom-tools/index";
|
|
62
|
+
export { discoverAndLoadCustomTools, loadCustomTools } from "./core/custom-tools/index";
|
|
63
|
+
export type * from "./core/hooks/index";
|
|
64
|
+
// Hook system types and type guards
|
|
65
|
+
export {
|
|
66
|
+
isBashToolResult,
|
|
67
|
+
isEditToolResult,
|
|
68
|
+
isFindToolResult,
|
|
69
|
+
isGrepToolResult,
|
|
70
|
+
isLsToolResult,
|
|
71
|
+
isReadToolResult,
|
|
72
|
+
isWriteToolResult,
|
|
73
|
+
} from "./core/hooks/index";
|
|
74
|
+
// Logging
|
|
75
|
+
export { type Logger, logger } from "./core/logger";
|
|
76
|
+
export { convertToLlm } from "./core/messages";
|
|
77
|
+
export { ModelRegistry } from "./core/model-registry";
|
|
78
|
+
// SDK for programmatic usage
|
|
79
|
+
export {
|
|
80
|
+
type BuildSystemPromptOptions,
|
|
81
|
+
buildSystemPrompt,
|
|
82
|
+
type CreateAgentSessionOptions,
|
|
83
|
+
type CreateAgentSessionResult,
|
|
84
|
+
// Factory
|
|
85
|
+
createAgentSession,
|
|
86
|
+
createBashTool,
|
|
87
|
+
// Tool factories (for custom cwd)
|
|
88
|
+
createCodingTools,
|
|
89
|
+
createEditTool,
|
|
90
|
+
createFindTool,
|
|
91
|
+
createGrepTool,
|
|
92
|
+
createLsTool,
|
|
93
|
+
createReadOnlyTools,
|
|
94
|
+
createReadTool,
|
|
95
|
+
createWriteTool,
|
|
96
|
+
// Discovery
|
|
97
|
+
discoverAuthStorage,
|
|
98
|
+
discoverContextFiles,
|
|
99
|
+
discoverCustomTools,
|
|
100
|
+
discoverHooks,
|
|
101
|
+
discoverModels,
|
|
102
|
+
discoverSkills,
|
|
103
|
+
discoverSlashCommands,
|
|
104
|
+
type FileSlashCommand,
|
|
105
|
+
// Hook types
|
|
106
|
+
type HookAPI,
|
|
107
|
+
type HookContext,
|
|
108
|
+
type HookFactory,
|
|
109
|
+
loadSettings,
|
|
110
|
+
// Pre-built tools (use process.cwd())
|
|
111
|
+
readOnlyTools,
|
|
112
|
+
} from "./core/sdk";
|
|
113
|
+
export {
|
|
114
|
+
type BranchSummaryEntry,
|
|
115
|
+
buildSessionContext,
|
|
116
|
+
type CompactionEntry,
|
|
117
|
+
CURRENT_SESSION_VERSION,
|
|
118
|
+
type CustomEntry,
|
|
119
|
+
type CustomMessageEntry,
|
|
120
|
+
type FileEntry,
|
|
121
|
+
getLatestCompactionEntry,
|
|
122
|
+
type ModelChangeEntry,
|
|
123
|
+
migrateSessionEntries,
|
|
124
|
+
type NewSessionOptions,
|
|
125
|
+
parseSessionEntries,
|
|
126
|
+
type SessionContext,
|
|
127
|
+
type SessionEntry,
|
|
128
|
+
type SessionEntryBase,
|
|
129
|
+
type SessionHeader,
|
|
130
|
+
type SessionInfo,
|
|
131
|
+
SessionManager,
|
|
132
|
+
type SessionMessageEntry,
|
|
133
|
+
type ThinkingLevelChangeEntry,
|
|
134
|
+
} from "./core/session-manager";
|
|
135
|
+
export {
|
|
136
|
+
type CompactionSettings,
|
|
137
|
+
type LspSettings,
|
|
138
|
+
type RetrySettings,
|
|
139
|
+
type Settings,
|
|
140
|
+
SettingsManager,
|
|
141
|
+
type SkillsSettings,
|
|
142
|
+
} from "./core/settings-manager";
|
|
143
|
+
// Skills
|
|
144
|
+
export {
|
|
145
|
+
formatSkillsForPrompt,
|
|
146
|
+
type LoadSkillsFromDirOptions,
|
|
147
|
+
type LoadSkillsResult,
|
|
148
|
+
loadSkills,
|
|
149
|
+
loadSkillsFromDir,
|
|
150
|
+
type Skill,
|
|
151
|
+
type SkillFrontmatter,
|
|
152
|
+
type SkillWarning,
|
|
153
|
+
} from "./core/skills";
|
|
154
|
+
// Tools
|
|
155
|
+
export {
|
|
156
|
+
type BashToolDetails,
|
|
157
|
+
bashTool,
|
|
158
|
+
type CodingToolsOptions,
|
|
159
|
+
codingTools,
|
|
160
|
+
editTool,
|
|
161
|
+
type FindToolDetails,
|
|
162
|
+
findTool,
|
|
163
|
+
type GrepToolDetails,
|
|
164
|
+
grepTool,
|
|
165
|
+
type LsToolDetails,
|
|
166
|
+
lsTool,
|
|
167
|
+
type ReadToolDetails,
|
|
168
|
+
readTool,
|
|
169
|
+
type TruncationResult,
|
|
170
|
+
type WriteToolDetails,
|
|
171
|
+
type WriteToolOptions,
|
|
172
|
+
writeTool,
|
|
173
|
+
} from "./core/tools/index";
|
|
174
|
+
export type { FileDiagnosticsResult } from "./core/tools/lsp/index";
|
|
175
|
+
// Main entry point
|
|
176
|
+
export { main } from "./main";
|
|
177
|
+
// UI components for hooks and custom tools
|
|
178
|
+
export { BorderedLoader } from "./modes/interactive/components/bordered-loader";
|
|
179
|
+
// Theme utilities for custom tools
|
|
180
|
+
export { getMarkdownTheme } from "./modes/interactive/theme/theme";
|
|
181
|
+
|
|
182
|
+
// TypeBox helper for string enums (convenience for custom tools)
|
|
183
|
+
import { type TSchema, Type } from "@sinclair/typebox";
|
|
184
|
+
export function StringEnum<T extends readonly string[]>(
|
|
185
|
+
values: T,
|
|
186
|
+
options?: { description?: string; default?: T[number] },
|
|
187
|
+
): TSchema {
|
|
188
|
+
return Type.Union(
|
|
189
|
+
values.map((v) => Type.Literal(v)),
|
|
190
|
+
options,
|
|
191
|
+
);
|
|
192
|
+
}
|