flowseeker 0.1.7

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.
Files changed (82) hide show
  1. package/CHANGELOG.md +111 -0
  2. package/COMPATIBILITY.md +281 -0
  3. package/LICENSE +21 -0
  4. package/README.md +375 -0
  5. package/dist/adapters/frameworkEdges.js +586 -0
  6. package/dist/agent/approvalPolicy.js +81 -0
  7. package/dist/agent/commandRunner.js +166 -0
  8. package/dist/agent/flowCommandRunner.js +124 -0
  9. package/dist/agent/mcpToolRunner.js +167 -0
  10. package/dist/auth/githubAuth.js +71 -0
  11. package/dist/auth/modelList.js +127 -0
  12. package/dist/auth/oauthHandler.js +377 -0
  13. package/dist/chat/nativeChatParticipant.js +616 -0
  14. package/dist/cli/mcpServer.js +383 -0
  15. package/dist/cli/runEvaluation.js +789 -0
  16. package/dist/cli/runReplay.js +481 -0
  17. package/dist/commands/checkHostCompatibility.js +149 -0
  18. package/dist/commands/copyAgentPrompt.js +52 -0
  19. package/dist/commands/copyContext.js +54 -0
  20. package/dist/commands/explainSelectionRelevance.js +57 -0
  21. package/dist/commands/findRelevantContext.js +127 -0
  22. package/dist/commands/openEvidence.js +49 -0
  23. package/dist/commands/openMcpConfig.js +81 -0
  24. package/dist/commands/openRelatedTests.js +54 -0
  25. package/dist/commands/rebuildIndex.js +45 -0
  26. package/dist/commands/runEvaluationSuite.js +323 -0
  27. package/dist/commands/runReplaySuite.js +228 -0
  28. package/dist/config/defaultConfig.js +72 -0
  29. package/dist/config/loadConfig.js +84 -0
  30. package/dist/config/loadConfigFromPath.js +60 -0
  31. package/dist/extension.js +513 -0
  32. package/dist/gateway/agentPrompts.js +176 -0
  33. package/dist/gateway/aiGateway.js +1255 -0
  34. package/dist/gateway/aiProviders.js +901 -0
  35. package/dist/gateway/contextExpansion.js +331 -0
  36. package/dist/gateway/editProposalStore.js +238 -0
  37. package/dist/gateway/planProposalStore.js +28 -0
  38. package/dist/index/cacheStore.js +51 -0
  39. package/dist/index/chunker.js +45 -0
  40. package/dist/index/dependencyExtractor.js +107 -0
  41. package/dist/index/fileDiscovery.js +177 -0
  42. package/dist/index/structuredExtractor.js +256 -0
  43. package/dist/index/workspaceIndex.js +518 -0
  44. package/dist/mcp/mcpConfig.js +154 -0
  45. package/dist/mcp/mcpProvider.js +109 -0
  46. package/dist/mcp/mcpTools.js +215 -0
  47. package/dist/pipeline/agentPrompt.js +79 -0
  48. package/dist/pipeline/agentPromptHeadless.js +85 -0
  49. package/dist/pipeline/contextBlueprint.js +346 -0
  50. package/dist/pipeline/contextPack.js +80 -0
  51. package/dist/pipeline/diffPreview.js +79 -0
  52. package/dist/pipeline/evaluationMetrics.js +154 -0
  53. package/dist/pipeline/evidenceGraph.js +389 -0
  54. package/dist/pipeline/feedback.js +215 -0
  55. package/dist/pipeline/fileGroups.js +84 -0
  56. package/dist/pipeline/fileScanner.js +866 -0
  57. package/dist/pipeline/nodeScan.js +219 -0
  58. package/dist/pipeline/ranker.js +563 -0
  59. package/dist/pipeline/responseLanguage.js +39 -0
  60. package/dist/pipeline/retrievalPlan.js +163 -0
  61. package/dist/pipeline/runHeadless.js +54 -0
  62. package/dist/pipeline/runPipeline.js +114 -0
  63. package/dist/pipeline/solvePacket.js +382 -0
  64. package/dist/pipeline/subsystem.js +257 -0
  65. package/dist/pipeline/taskUnderstanding.js +453 -0
  66. package/dist/pipeline/tokenSavings.js +146 -0
  67. package/dist/pipeline/universalScan.js +216 -0
  68. package/dist/pipeline/verifyAfterApply.js +233 -0
  69. package/dist/runtime/capabilities.js +71 -0
  70. package/dist/runtime/hostDetect.js +98 -0
  71. package/dist/runtime/hostTier.js +68 -0
  72. package/dist/runtime/statusBar.js +80 -0
  73. package/dist/skills/skillRegistry.js +208 -0
  74. package/dist/types.js +3 -0
  75. package/dist/ui/chatViewProvider.js +3899 -0
  76. package/dist/ui/resultTreeProvider.js +174 -0
  77. package/dist/usage/quotaTracker.js +358 -0
  78. package/dist/utils/async.js +30 -0
  79. package/dist/utils/logger.js +64 -0
  80. package/dist/utils/text.js +364 -0
  81. package/dist/utils/updateChecker.js +140 -0
  82. package/package.json +561 -0
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.loadConfig = loadConfig;
37
+ const vscode = __importStar(require("vscode"));
38
+ const defaultConfig_1 = require("./defaultConfig");
39
+ async function loadConfig() {
40
+ const workspaceConfig = await readWorkspaceConfig();
41
+ const vscodeConfig = vscode.workspace.getConfiguration("flowseeker");
42
+ const merged = (0, defaultConfig_1.mergeConfig)(defaultConfig_1.defaultConfig, workspaceConfig);
43
+ merged.project.include = readArray(vscodeConfig, "project.include", merged.project.include);
44
+ merged.project.exclude = readArray(vscodeConfig, "project.exclude", merged.project.exclude);
45
+ merged.project.maxFileSizeKb = vscodeConfig.get("project.maxFileSizeKb", merged.project.maxFileSizeKb);
46
+ merged.index.enableWorkspaceIndex = vscodeConfig.get("index.enableWorkspaceIndex", merged.index.enableWorkspaceIndex);
47
+ merged.index.chunkSizeLines = vscodeConfig.get("index.chunkSizeLines", merged.index.chunkSizeLines);
48
+ merged.index.chunkOverlapLines = vscodeConfig.get("index.chunkOverlapLines", merged.index.chunkOverlapLines);
49
+ merged.index.enableDependencyExpansion = vscodeConfig.get("index.enableDependencyExpansion", merged.index.enableDependencyExpansion);
50
+ merged.index.maxSeedCandidateFiles = vscodeConfig.get("index.maxSeedCandidateFiles", merged.index.maxSeedCandidateFiles);
51
+ merged.index.maxDependencyExpansionFiles = vscodeConfig.get("index.maxDependencyExpansionFiles", merged.index.maxDependencyExpansionFiles);
52
+ merged.index.maxIndexedCandidateFiles = vscodeConfig.get("index.maxIndexedCandidateFiles", merged.index.maxIndexedCandidateFiles);
53
+ merged.ai.enabled = vscodeConfig.get("ai.enabled", merged.ai.enabled);
54
+ merged.ai.outputLanguage = vscodeConfig.get("ai.outputLanguage", merged.ai.outputLanguage);
55
+ merged.pipeline.maxCandidates = vscodeConfig.get("pipeline.maxCandidates", merged.pipeline.maxCandidates);
56
+ merged.pipeline.maxContextTokens = vscodeConfig.get("pipeline.maxContextTokens", merged.pipeline.maxContextTokens);
57
+ merged.pipeline.graphDepth = vscodeConfig.get("pipeline.graphDepth", merged.pipeline.graphDepth);
58
+ merged.pipeline.minConfidence = vscodeConfig.get("pipeline.minConfidence", merged.pipeline.minConfidence);
59
+ merged.pipeline.maxFiles = vscodeConfig.get("pipeline.maxFiles", merged.pipeline.maxFiles);
60
+ merged.pipeline.maxTotalBytesMb = vscodeConfig.get("pipeline.maxTotalBytesMb", merged.pipeline.maxTotalBytesMb);
61
+ merged.pipeline.maxScanMs = vscodeConfig.get("pipeline.maxScanMs", merged.pipeline.maxScanMs);
62
+ merged.pipeline.maxRawEvidence = vscodeConfig.get("pipeline.maxRawEvidence", merged.pipeline.maxRawEvidence);
63
+ return merged;
64
+ }
65
+ async function readWorkspaceConfig() {
66
+ const folders = vscode.workspace.workspaceFolders;
67
+ if (!folders || folders.length === 0) {
68
+ return {};
69
+ }
70
+ const uri = vscode.Uri.joinPath(folders[0].uri, ".flowseeker", "config.json");
71
+ try {
72
+ const bytes = await vscode.workspace.fs.readFile(uri);
73
+ const text = new TextDecoder("utf-8").decode(bytes);
74
+ return JSON.parse(text);
75
+ }
76
+ catch {
77
+ return {};
78
+ }
79
+ }
80
+ function readArray(config, key, fallback) {
81
+ const value = config.get(key);
82
+ return Array.isArray(value) && value.length > 0 ? value : fallback;
83
+ }
84
+ //# sourceMappingURL=loadConfig.js.map
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.loadConfigFromPath = loadConfigFromPath;
37
+ const fs = __importStar(require("fs/promises"));
38
+ const path = __importStar(require("path"));
39
+ const defaultConfig_1 = require("./defaultConfig");
40
+ async function loadConfigFromPath(workspacePath) {
41
+ const configPath = path.join(workspacePath, ".flowseeker", "config.json");
42
+ const workspaceConfig = await readJson(configPath);
43
+ return (0, defaultConfig_1.mergeConfig)(defaultConfig_1.defaultConfig, workspaceConfig ?? {});
44
+ }
45
+ async function readJson(filePath) {
46
+ try {
47
+ const text = await fs.readFile(filePath, "utf8");
48
+ return JSON.parse(text);
49
+ }
50
+ catch (error) {
51
+ if (isNodeError(error) && error.code === "ENOENT") {
52
+ return undefined;
53
+ }
54
+ throw error;
55
+ }
56
+ }
57
+ function isNodeError(error) {
58
+ return error instanceof Error && "code" in error;
59
+ }
60
+ //# sourceMappingURL=loadConfigFromPath.js.map
@@ -0,0 +1,513 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.activate = activate;
37
+ exports.deactivate = deactivate;
38
+ const vscode = __importStar(require("vscode"));
39
+ const copyAgentPrompt_1 = require("./commands/copyAgentPrompt");
40
+ const checkHostCompatibility_1 = require("./commands/checkHostCompatibility");
41
+ const copyContext_1 = require("./commands/copyContext");
42
+ const explainSelectionRelevance_1 = require("./commands/explainSelectionRelevance");
43
+ const findRelevantContext_1 = require("./commands/findRelevantContext");
44
+ const openEvidence_1 = require("./commands/openEvidence");
45
+ const openMcpConfig_1 = require("./commands/openMcpConfig");
46
+ const openRelatedTests_1 = require("./commands/openRelatedTests");
47
+ const rebuildIndex_1 = require("./commands/rebuildIndex");
48
+ const runEvaluationSuite_1 = require("./commands/runEvaluationSuite");
49
+ const runReplaySuite_1 = require("./commands/runReplaySuite");
50
+ const nativeChatParticipant_1 = require("./chat/nativeChatParticipant");
51
+ const approvalPolicy_1 = require("./agent/approvalPolicy");
52
+ const commandRunner_1 = require("./agent/commandRunner");
53
+ const mcpToolRunner_1 = require("./agent/mcpToolRunner");
54
+ const aiGateway_1 = require("./gateway/aiGateway");
55
+ const aiProviders_1 = require("./gateway/aiProviders");
56
+ const editProposalStore_1 = require("./gateway/editProposalStore");
57
+ const planProposalStore_1 = require("./gateway/planProposalStore");
58
+ const mcpProvider_1 = require("./mcp/mcpProvider");
59
+ const verifyAfterApply_1 = require("./pipeline/verifyAfterApply");
60
+ const capabilities_1 = require("./runtime/capabilities");
61
+ const hostDetect_1 = require("./runtime/hostDetect");
62
+ const hostTier_1 = require("./runtime/hostTier");
63
+ const statusBar_1 = require("./runtime/statusBar");
64
+ const chatViewProvider_1 = require("./ui/chatViewProvider");
65
+ const resultTreeProvider_1 = require("./ui/resultTreeProvider");
66
+ const logger_1 = require("./utils/logger");
67
+ const updateChecker_1 = require("./utils/updateChecker");
68
+ const oauthHandler_1 = require("./auth/oauthHandler");
69
+ const githubAuth_1 = require("./auth/githubAuth");
70
+ const skillRegistry_1 = require("./skills/skillRegistry");
71
+ const quotaTracker_1 = require("./usage/quotaTracker");
72
+ async function activate(context) {
73
+ (0, logger_1.initializeLogger)(context);
74
+ (0, logger_1.logInfo)("FlowSeeker extension activated.");
75
+ void (0, updateChecker_1.checkForExtensionUpdate)(context);
76
+ // Host detection and logging
77
+ const hostIdentity = (0, hostDetect_1.detectHost)();
78
+ const hostCapabilities = (0, capabilities_1.getHostCapabilities)(context);
79
+ const tier = (0, hostTier_1.getHostTier)();
80
+ (0, logger_1.logInfo)(`Host: ${hostIdentity.appName} ${hostIdentity.version} (detected: ${hostIdentity.id}, tier: ${tier.tier})`);
81
+ (0, hostDetect_1.probeLanguageModels)(hostCapabilities).then((probe) => {
82
+ for (const line of (0, hostDetect_1.summarizeProbe)(hostIdentity, hostCapabilities, probe)) {
83
+ (0, logger_1.logInfo)(line);
84
+ }
85
+ });
86
+ const quotaTracker = new quotaTracker_1.QuotaTracker(context);
87
+ const provider = new resultTreeProvider_1.ResultTreeProvider();
88
+ const gateway = new aiGateway_1.AiGatewayClient(context, quotaTracker);
89
+ const editStore = new editProposalStore_1.EditProposalStore();
90
+ const planStore = new planProposalStore_1.PlanProposalStore();
91
+ const skillRegistry = new skillRegistry_1.SkillRegistry(context);
92
+ await skillRegistry.loadWorkspaceSkills();
93
+ const skillWatcher = skillRegistry.startWatching();
94
+ const chatViewProvider = new chatViewProvider_1.ChatViewProvider(context, provider, gateway, editStore, planStore, quotaTracker);
95
+ const treeView = vscode.window.createTreeView("flowseeker.results", {
96
+ treeDataProvider: provider,
97
+ showCollapseAll: true
98
+ });
99
+ treeView.onDidChangeCheckboxState((event) => {
100
+ for (const [node, state] of event.items) {
101
+ if (node.type === "evidence" && node.unit) {
102
+ provider.setChecked(node.unit.id, state === vscode.TreeItemCheckboxState.Checked);
103
+ }
104
+ }
105
+ });
106
+ context.subscriptions.push(treeView, (0, statusBar_1.registerFlowSeekerStatusBar)(context), vscode.window.registerWebviewViewProvider(chatViewProvider_1.ChatViewProvider.viewType, chatViewProvider), vscode.commands.registerCommand("flowseeker.openChat", async () => {
107
+ await openNativeChat();
108
+ }), vscode.commands.registerCommand("flowseeker.connectGateway", () => connectGateway(gateway)), vscode.commands.registerCommand("flowseeker.disconnectGateway", () => disconnectGateway(gateway)), vscode.commands.registerCommand("flowseeker.approvePlan", (planId) => approvePlan(planId)), vscode.commands.registerCommand("flowseeker.applyGatewayEdits", (proposalId) => applyGatewayEdits(editStore, proposalId)), vscode.commands.registerCommand("flowseeker.openGatewayDiff", (proposalId) => openGatewayDiff(editStore, proposalId)), vscode.commands.registerCommand("flowseeker.runAgentCommand", (proposal) => runAgentCommand(proposal)), vscode.commands.registerCommand("flowseeker.runMcpTool", (proposal) => runMcpTool(proposal)), vscode.commands.registerCommand("flowseeker.openMcpConfig", () => (0, openMcpConfig_1.openMcpConfig)()), vscode.commands.registerCommand("flowseeker.findRelevantContext", () => (0, findRelevantContext_1.findRelevantContext)(provider)), vscode.commands.registerCommand("flowseeker.copyContext", () => (0, copyContext_1.copyContext)(provider)), vscode.commands.registerCommand("flowseeker.copyAgentPrompt", () => (0, copyAgentPrompt_1.copyAgentPrompt)(provider)), vscode.commands.registerCommand("flowseeker.rebuildIndex", () => (0, rebuildIndex_1.rebuildIndex)()), vscode.commands.registerCommand("flowseeker.runEvaluationSuite", () => (0, runEvaluationSuite_1.runEvaluationSuite)()), vscode.commands.registerCommand("flowseeker.runReplaySuite", () => (0, runReplaySuite_1.runReplaySuite)()), vscode.commands.registerCommand("flowseeker.checkHostCompatibility", () => (0, checkHostCompatibility_1.checkHostCompatibility)(context)), vscode.commands.registerCommand("flowseeker.explainSelectionRelevance", () => (0, explainSelectionRelevance_1.explainSelectionRelevance)(provider)), vscode.commands.registerCommand("flowseeker.openRelatedTests", () => (0, openRelatedTests_1.openRelatedTests)(provider)), vscode.commands.registerCommand("flowseeker.openEvidence", (unit) => (0, openEvidence_1.openEvidence)(unit)), vscode.commands.registerCommand("flowseeker.verifyAfterEdits", () => verifyAfterEditsFromLastApply(editStore)), vscode.commands.registerCommand("flowseeker.showLog", () => (0, logger_1.showLog)()), vscode.commands.registerCommand("flowseeker.startOAuth", (providerId) => startOAuth(gateway, chatViewProvider, context, providerId)), vscode.commands.registerCommand("flowseeker.oauthComplete", async (providerId) => {
109
+ try {
110
+ await gateway.handleOAuthCallback(providerId, "");
111
+ await chatViewProvider.refreshConnectionState();
112
+ await vscode.window.showInformationMessage(`Connected to ${providerId}.`);
113
+ }
114
+ catch (error) {
115
+ (0, logger_1.logError)("OAuth callback failed.", error);
116
+ await vscode.window.showErrorMessage(`Authentication failed: ${error instanceof Error ? error.message : String(error)}`);
117
+ }
118
+ }), vscode.commands.registerCommand("flowseeker.runSkill", async (skillName) => {
119
+ const skill = skillRegistry.getSkill(skillName);
120
+ if (!skill) {
121
+ await vscode.window.showErrorMessage(`Skill "${skillName}" not found.`);
122
+ return;
123
+ }
124
+ await openNativeChatWithSkill(skill);
125
+ }), vscode.commands.registerCommand("flowseeker.pickSkill", async () => {
126
+ const skills = skillRegistry.getAllSkills();
127
+ const picked = await vscode.window.showQuickPick(skills.map((s) => ({ label: s.name, description: s.description, skill: s })), { title: "FlowSeeker Skills", placeHolder: "Choose a skill" });
128
+ if (picked) {
129
+ await openNativeChatWithSkill(picked.skill);
130
+ }
131
+ }), vscode.commands.registerCommand("flowseeker.reloadSkills", async () => {
132
+ await skillRegistry.loadWorkspaceSkills();
133
+ await vscode.window.showInformationMessage(`FlowSeeker skills reloaded. ${skillRegistry.getAllSkills().length} skills available.`);
134
+ }), vscode.commands.registerCommand("flowseeker.showUsage", () => showUsage(quotaTracker)), vscode.commands.registerCommand("flowseeker.setBudget", () => setBudget(quotaTracker)), vscode.commands.registerCommand("flowseeker.clearUsage", () => clearUsage(quotaTracker)));
135
+ const nativeChat = tryRegisterNativeChatParticipant(context, provider, gateway, editStore, planStore, skillRegistry);
136
+ if (nativeChat) {
137
+ context.subscriptions.push(nativeChat);
138
+ }
139
+ else {
140
+ // On non-VS Code hosts (Cursor, Antigravity, Windsurf, etc.) native chat participant
141
+ // is unavailable. Guide the user toward sidebar chat or MCP configuration.
142
+ notifyNonNativeChatHost(hostIdentity);
143
+ }
144
+ context.subscriptions.push(skillWatcher);
145
+ const mcpProvider = (0, mcpProvider_1.registerFlowSeekerMcpProvider)(context);
146
+ if (mcpProvider) {
147
+ context.subscriptions.push(mcpProvider);
148
+ }
149
+ (0, logger_1.logInfo)("FlowSeeker commands and result tree registered.");
150
+ }
151
+ function deactivate() { }
152
+ async function openNativeChat() {
153
+ if (!hasNativeChatApi()) {
154
+ await vscode.commands.executeCommand("flowseeker.chatView.focus");
155
+ return;
156
+ }
157
+ try {
158
+ await vscode.commands.executeCommand("workbench.action.chat.open", { query: "@flowseeker " });
159
+ }
160
+ catch (error) {
161
+ (0, logger_1.logError)("Unable to open native chat.", error);
162
+ await vscode.commands.executeCommand("flowseeker.chatView.focus");
163
+ }
164
+ }
165
+ async function openNativeChatWithSkill(skill) {
166
+ if (!hasNativeChatApi()) {
167
+ await vscode.commands.executeCommand("flowseeker.chatView.focus");
168
+ return;
169
+ }
170
+ try {
171
+ const query = `@flowseeker /${skill.name} `;
172
+ await vscode.commands.executeCommand("workbench.action.chat.open", { query });
173
+ }
174
+ catch (error) {
175
+ (0, logger_1.logError)("Unable to open native chat with skill.", error);
176
+ await vscode.commands.executeCommand("flowseeker.chatView.focus");
177
+ }
178
+ }
179
+ function tryRegisterNativeChatParticipant(context, provider, gateway, editStore, planStore, skillRegistry) {
180
+ if (!hasNativeChatApi()) {
181
+ (0, logger_1.logInfo)("Native VS Code Chat API is unavailable. FlowSeeker will use the sidebar chat fallback.");
182
+ return undefined;
183
+ }
184
+ try {
185
+ return (0, nativeChatParticipant_1.registerNativeChatParticipant)(context, provider, gateway, editStore, planStore, skillRegistry);
186
+ }
187
+ catch (error) {
188
+ (0, logger_1.logError)("Unable to register native chat participant. FlowSeeker will use the sidebar chat fallback.", error);
189
+ return undefined;
190
+ }
191
+ }
192
+ function hasNativeChatApi() {
193
+ return (0, capabilities_1.getHostCapabilities)().hasNativeChat;
194
+ }
195
+ function notifyNonNativeChatHost(host) {
196
+ const isKnownAiHost = ["cursor", "antigravity", "windsurf"].includes(host.id);
197
+ if (!isKnownAiHost) {
198
+ return;
199
+ }
200
+ const hostLabel = host.appName || host.id;
201
+ (0, logger_1.logInfo)(`Non-VS Code AI host detected: ${hostLabel}. Native @flowseeker chat is unavailable. Sidebar chat and MCP are recommended.`);
202
+ // Show a one-time information message guiding the user
203
+ const message = `FlowSeeker: @flowseeker chat is not available in ${hostLabel}'s native chat. Use the FlowSeeker sidebar or configure FlowSeeker as an MCP server for full integration.`;
204
+ void vscode.window.showInformationMessage(message, "Open Sidebar", "MCP Setup Guide").then((action) => {
205
+ if (action === "Open Sidebar") {
206
+ void vscode.commands.executeCommand("flowseeker.chatView.focus");
207
+ }
208
+ else if (action === "MCP Setup Guide") {
209
+ void vscode.commands.executeCommand("flowseeker.checkHostCompatibility");
210
+ }
211
+ });
212
+ }
213
+ async function connectGateway(gateway) {
214
+ const picked = await vscode.window.showQuickPick(aiProviders_1.AI_PROVIDER_DEFINITIONS.map((provider) => ({
215
+ label: provider.label,
216
+ description: provider.id === "customGateway" ? "OpenAI-compatible /v1 chat completions" : provider.id === "customAnthropic" ? "Anthropic-compatible /v1 messages" : provider.authMethod === "local_cli" ? "Local CLI agent" : provider.authMethod === "oauth" ? "OAuth sign-in" : provider.defaultModel,
217
+ provider
218
+ })), {
219
+ title: "FlowSeeker AI Provider",
220
+ placeHolder: "Choose an AI provider"
221
+ });
222
+ if (!picked) {
223
+ return;
224
+ }
225
+ const provider = picked.provider;
226
+ const isOAuth = provider.authMethod === "oauth";
227
+ const isLocalCli = provider.authMethod === "local_cli";
228
+ const isCustom = provider.id === "customGateway" || provider.id === "customAnthropic";
229
+ if (isOAuth) {
230
+ await vscode.commands.executeCommand("flowseeker.startOAuth", provider.id);
231
+ return;
232
+ }
233
+ const baseUrl = await vscode.window.showInputBox({
234
+ title: "FlowSeeker AI Provider",
235
+ prompt: isLocalCli ? `${provider.label} command or executable path` : isCustom ? `${provider.label} API base URL` : `${provider.label} base URL`,
236
+ value: provider.defaultBaseUrl,
237
+ placeHolder: provider.defaultBaseUrl || (isLocalCli ? "codex" : "https://api.example.com/v1"),
238
+ ignoreFocusOut: true
239
+ });
240
+ if (!baseUrl) {
241
+ return;
242
+ }
243
+ const apiKey = provider.requiresApiKey
244
+ ? await vscode.window.showInputBox({
245
+ title: "FlowSeeker AI Provider",
246
+ prompt: provider.apiKeyHint ? `${provider.apiKeyLabel} (${provider.apiKeyHint})` : provider.apiKeyLabel,
247
+ password: true,
248
+ ignoreFocusOut: true
249
+ })
250
+ : "";
251
+ if (provider.requiresApiKey && !apiKey) {
252
+ return;
253
+ }
254
+ let model = provider.defaultModel;
255
+ if (provider.supportsModelList && !isCustom && !isLocalCli) {
256
+ const models = await vscode.window.withProgress({
257
+ location: vscode.ProgressLocation.Notification,
258
+ title: `Loading ${provider.label} models`,
259
+ cancellable: false
260
+ }, () => gateway.listModelsForInput({
261
+ provider: provider.id,
262
+ baseUrl,
263
+ model: provider.defaultModel,
264
+ apiKey
265
+ }));
266
+ if (models.length > 0) {
267
+ const pickedModel = await vscode.window.showQuickPick(models.map((item) => ({
268
+ label: item.id,
269
+ description: item.name && item.name !== item.id ? item.name : item.owned_by,
270
+ model: item.id
271
+ })), {
272
+ title: `${provider.label} Model`,
273
+ placeHolder: "Choose a model"
274
+ });
275
+ if (!pickedModel) {
276
+ return;
277
+ }
278
+ model = pickedModel.model;
279
+ }
280
+ else {
281
+ await vscode.window.showWarningMessage(`Could not load ${provider.label} models. You can enter the model manually for now.`);
282
+ const manualModel = await vscode.window.showInputBox({
283
+ title: "FlowSeeker AI Provider",
284
+ prompt: `${provider.label} model`,
285
+ value: provider.defaultModel,
286
+ placeHolder: provider.defaultModel,
287
+ ignoreFocusOut: true
288
+ });
289
+ if (!manualModel) {
290
+ return;
291
+ }
292
+ model = manualModel;
293
+ }
294
+ }
295
+ else {
296
+ const manualModel = await vscode.window.showInputBox({
297
+ title: "FlowSeeker AI Provider",
298
+ prompt: isLocalCli ? `${provider.label} model name, or "default"` : isCustom ? "Model name exposed by this endpoint" : `${provider.label} model`,
299
+ value: provider.defaultModel,
300
+ placeHolder: isCustom ? "claude-sonnet-4-5" : isLocalCli ? "default" : provider.defaultModel,
301
+ ignoreFocusOut: true
302
+ });
303
+ if (!manualModel) {
304
+ return;
305
+ }
306
+ model = manualModel;
307
+ }
308
+ await gateway.configureProvider({
309
+ provider: provider.id,
310
+ baseUrl,
311
+ model,
312
+ apiKey
313
+ });
314
+ await vscode.window.showInformationMessage(`FlowSeeker AI provider connected: ${provider.label}.`);
315
+ }
316
+ async function disconnectGateway(gateway) {
317
+ await gateway.disconnect();
318
+ await vscode.window.showInformationMessage("FlowSeeker AI provider disconnected.");
319
+ }
320
+ async function approvePlan(planId) {
321
+ const query = `@flowseeker /apply ${planId}`;
322
+ try {
323
+ await vscode.commands.executeCommand("workbench.action.chat.open", { query });
324
+ }
325
+ catch (error) {
326
+ (0, logger_1.logError)("Unable to open approved plan chat.", error);
327
+ await vscode.env.clipboard.writeText(query);
328
+ await vscode.window.showInformationMessage("Approval command copied. Open VSCode Chat and paste it to generate edits.");
329
+ }
330
+ }
331
+ let lastAppliedFiles = [];
332
+ async function applyGatewayEdits(editStore, proposalId) {
333
+ try {
334
+ const summary = await editStore.apply(proposalId);
335
+ lastAppliedFiles = summary.files;
336
+ const policy = (0, approvalPolicy_1.getApprovalPolicy)();
337
+ if (policy.safeCommands || policy.allCommands) {
338
+ await vscode.window.showInformationMessage(`FlowSeeker applied ${summary.editCount} edit(s). Auto-running verification...`);
339
+ const run = await (0, verifyAfterApply_1.verifyAfterEdits)(summary.files);
340
+ if (run) {
341
+ await vscode.window.showInformationMessage((0, verifyAfterApply_1.summarizeVerificationRun)(run));
342
+ }
343
+ return;
344
+ }
345
+ const action = await vscode.window.showInformationMessage(`FlowSeeker applied ${summary.editCount} edit(s) to ${summary.fileCount} file(s).`, "Verify Changes", "Dismiss");
346
+ if (action === "Verify Changes") {
347
+ await (0, verifyAfterApply_1.verifyAfterEdits)(summary.files);
348
+ }
349
+ }
350
+ catch (error) {
351
+ const message = error instanceof Error ? error.message : String(error);
352
+ await vscode.window.showErrorMessage(message);
353
+ }
354
+ }
355
+ async function openGatewayDiff(editStore, proposalId) {
356
+ try {
357
+ const folders = vscode.workspace.workspaceFolders;
358
+ if (!folders?.[0]) {
359
+ await vscode.window.showWarningMessage("Open a workspace folder before previewing FlowSeeker edits.");
360
+ return;
361
+ }
362
+ const files = editStore.listFiles(proposalId);
363
+ if (files.length === 0) {
364
+ await vscode.window.showWarningMessage("FlowSeeker diff preview is no longer available.");
365
+ return;
366
+ }
367
+ const file = files.length === 1
368
+ ? files[0]
369
+ : await vscode.window.showQuickPick(files, {
370
+ title: "FlowSeeker Proposed Diff",
371
+ placeHolder: "Choose a file to preview"
372
+ });
373
+ if (!file) {
374
+ return;
375
+ }
376
+ const preview = await editStore.previewFile(folders[0].uri, proposalId, file);
377
+ const document = await vscode.workspace.openTextDocument({
378
+ language: preview.languageId,
379
+ content: preview.text
380
+ });
381
+ await vscode.commands.executeCommand("vscode.diff", preview.originalUri, document.uri, `FlowSeeker Diff: ${preview.file}`, { preview: false, viewColumn: vscode.ViewColumn.Beside });
382
+ }
383
+ catch (error) {
384
+ const message = error instanceof Error ? error.message : String(error);
385
+ await vscode.window.showErrorMessage(message);
386
+ }
387
+ }
388
+ async function runAgentCommand(proposal) {
389
+ if (!proposal?.command) {
390
+ await vscode.window.showWarningMessage("No FlowSeeker agent command was provided.");
391
+ return;
392
+ }
393
+ try {
394
+ const run = await (0, commandRunner_1.runAgentCommandProposal)(proposal);
395
+ if (run) {
396
+ await vscode.window.showInformationMessage((0, commandRunner_1.summarizeAgentCommandRun)(run));
397
+ }
398
+ }
399
+ catch (error) {
400
+ (0, logger_1.logError)("FlowSeeker agent command failed.", error);
401
+ const message = error instanceof Error ? error.message : String(error);
402
+ await vscode.window.showErrorMessage(message);
403
+ }
404
+ }
405
+ async function runMcpTool(proposal) {
406
+ if (!proposal?.tool) {
407
+ await vscode.window.showWarningMessage("No FlowSeeker MCP/tool proposal was provided.");
408
+ return;
409
+ }
410
+ try {
411
+ const run = await (0, mcpToolRunner_1.runMcpToolProposal)(proposal);
412
+ if (run) {
413
+ await vscode.window.showInformationMessage((0, mcpToolRunner_1.summarizeMcpToolRun)(run));
414
+ }
415
+ }
416
+ catch (error) {
417
+ (0, logger_1.logError)("FlowSeeker MCP/tool invocation failed.", error);
418
+ const message = error instanceof Error ? error.message : String(error);
419
+ await vscode.window.showErrorMessage(message);
420
+ }
421
+ }
422
+ async function verifyAfterEditsFromLastApply(editStore) {
423
+ if (lastAppliedFiles.length === 0) {
424
+ await vscode.window.showInformationMessage("No edits have been applied yet. Apply edits first, then verify.");
425
+ return;
426
+ }
427
+ await (0, verifyAfterApply_1.verifyAfterEdits)(lastAppliedFiles);
428
+ }
429
+ async function startOAuth(gateway, chatViewProvider, context, providerId) {
430
+ const id = providerId;
431
+ const definition = (0, aiProviders_1.getProviderDefinition)(id);
432
+ if (definition.authMethod !== "oauth" || !definition.oauthConfig) {
433
+ await vscode.window.showInformationMessage(`${definition.label} browser sign-in is not available in FlowSeeker yet. Use API key, Custom Gateway, Codex CLI, or Claude Code instead.`);
434
+ return;
435
+ }
436
+ // GitHub Models: use VS Code built-in GitHub auth (popup, no browser)
437
+ if (id === "githubModels") {
438
+ try {
439
+ const session = await (0, githubAuth_1.getGitHubSession)();
440
+ if (!session) {
441
+ return;
442
+ }
443
+ await context.secrets.store("flowseeker.oauth.githubModels.accessToken", session.accessToken);
444
+ await gateway.handleOAuthCallback("githubModels", "");
445
+ await chatViewProvider.refreshConnectionState();
446
+ await vscode.window.showInformationMessage(`Connected to GitHub Models as ${session.accountLabel}.`);
447
+ }
448
+ catch (error) {
449
+ (0, logger_1.logError)("GitHub Models auth failed.", error);
450
+ await vscode.window.showErrorMessage(`GitHub authentication failed: ${error instanceof Error ? error.message : String(error)}`);
451
+ }
452
+ return;
453
+ }
454
+ // Other providers: browser-based OAuth with local HTTP server
455
+ const config = {
456
+ providerId: id,
457
+ authorizeUrl: definition.oauthConfig.authorizeUrl,
458
+ tokenUrl: definition.oauthConfig.tokenUrl,
459
+ clientId: definition.oauthConfig.clientId,
460
+ scopes: definition.oauthConfig.scopes,
461
+ redirectUri: ""
462
+ };
463
+ try {
464
+ await (0, oauthHandler_1.startOAuthFlow)(context, config);
465
+ }
466
+ catch (error) {
467
+ (0, logger_1.logError)("Failed to start OAuth flow.", error);
468
+ await vscode.window.showErrorMessage(`Failed to start authentication: ${error instanceof Error ? error.message : String(error)}`);
469
+ }
470
+ }
471
+ async function showUsage(quotaTracker) {
472
+ const summary = quotaTracker.getSummary();
473
+ const doc = await vscode.workspace.openTextDocument({
474
+ content: (0, quotaTracker_1.formatUsageSummary)(summary),
475
+ language: "markdown"
476
+ });
477
+ await vscode.window.showTextDocument(doc, { preview: true });
478
+ }
479
+ async function setBudget(quotaTracker) {
480
+ const current = quotaTracker.getBudget();
481
+ const input = await vscode.window.showInputBox({
482
+ title: "FlowSeeker Daily Budget",
483
+ prompt: "Set a daily spending limit in USD (0 = no limit)",
484
+ value: current > 0 ? String(current) : "",
485
+ placeHolder: "0",
486
+ validateInput: (value) => {
487
+ const n = Number(value);
488
+ if (value && (isNaN(n) || n < 0)) {
489
+ return "Enter a valid dollar amount (e.g., 5.00)";
490
+ }
491
+ return undefined;
492
+ }
493
+ });
494
+ if (input === undefined) {
495
+ return;
496
+ }
497
+ const limit = Number(input) || 0;
498
+ await quotaTracker.setBudget(limit);
499
+ if (limit > 0) {
500
+ await vscode.window.showInformationMessage(`Daily budget set to $${limit.toFixed(2)}. You'll be warned at 75% and blocked at 100%.`);
501
+ }
502
+ else {
503
+ await vscode.window.showInformationMessage("Daily budget disabled.");
504
+ }
505
+ }
506
+ async function clearUsage(quotaTracker) {
507
+ const choice = await vscode.window.showWarningMessage("Clear all usage history? This cannot be undone.", { modal: true }, "Clear");
508
+ if (choice === "Clear") {
509
+ await quotaTracker.clearHistory();
510
+ await vscode.window.showInformationMessage("Usage history cleared.");
511
+ }
512
+ }
513
+ //# sourceMappingURL=extension.js.map