@countfinancial/cli 0.1.6 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -1
- package/dist/__tests__/doctor.test.d.ts +1 -0
- package/dist/__tests__/doctor.test.js +30 -0
- package/dist/__tests__/doctor.test.js.map +1 -0
- package/dist/__tests__/mcpInstall.test.d.ts +1 -0
- package/dist/__tests__/mcpInstall.test.js +25 -0
- package/dist/__tests__/mcpInstall.test.js.map +1 -0
- package/dist/__tests__/profileStore.test.d.ts +1 -0
- package/dist/__tests__/profileStore.test.js +53 -0
- package/dist/__tests__/profileStore.test.js.map +1 -0
- package/dist/cli.js +108 -9
- package/dist/cli.js.map +1 -1
- package/dist/commands/doctor.command.d.ts +6 -0
- package/dist/commands/doctor.command.js +12 -0
- package/dist/commands/doctor.command.js.map +1 -0
- package/dist/commands/init.command.d.ts +1 -0
- package/dist/commands/init.command.js +6 -1
- package/dist/commands/init.command.js.map +1 -1
- package/dist/commands/login.command.d.ts +1 -0
- package/dist/commands/login.command.js +3 -3
- package/dist/commands/login.command.js.map +1 -1
- package/dist/commands/logout.command.d.ts +5 -1
- package/dist/commands/logout.command.js +3 -3
- package/dist/commands/logout.command.js.map +1 -1
- package/dist/commands/mcp.command.d.ts +5 -1
- package/dist/commands/mcp.command.js +7 -4
- package/dist/commands/mcp.command.js.map +1 -1
- package/dist/commands/mcpInstall.command.d.ts +7 -0
- package/dist/commands/mcpInstall.command.js +9 -0
- package/dist/commands/mcpInstall.command.js.map +1 -0
- package/dist/commands/profiles.command.d.ts +17 -0
- package/dist/commands/profiles.command.js +48 -0
- package/dist/commands/profiles.command.js.map +1 -0
- package/dist/commands/setup.command.d.ts +11 -0
- package/dist/commands/setup.command.js +85 -0
- package/dist/commands/setup.command.js.map +1 -0
- package/dist/commands/status.command.d.ts +6 -1
- package/dist/commands/status.command.js +7 -4
- package/dist/commands/status.command.js.map +1 -1
- package/dist/partner-mcp/config.js +1 -1
- package/dist/partner-mcp/helpers/mcpKnowledge.helper.d.ts +19 -0
- package/dist/partner-mcp/helpers/mcpKnowledge.helper.js +293 -0
- package/dist/partner-mcp/helpers/mcpKnowledge.helper.js.map +1 -0
- package/dist/partner-mcp/helpers/mcpPayloadValidation.helper.d.ts +42 -0
- package/dist/partner-mcp/helpers/mcpPayloadValidation.helper.js +741 -0
- package/dist/partner-mcp/helpers/mcpPayloadValidation.helper.js.map +1 -0
- package/dist/partner-mcp/helpers/mcpPlaybooks.helper.d.ts +26 -0
- package/dist/partner-mcp/helpers/mcpPlaybooks.helper.js +210 -0
- package/dist/partner-mcp/helpers/mcpPlaybooks.helper.js.map +1 -0
- package/dist/partner-mcp/helpers/mcpRecoveryHint.helper.d.ts +22 -0
- package/dist/partner-mcp/helpers/mcpRecoveryHint.helper.js +203 -0
- package/dist/partner-mcp/helpers/mcpRecoveryHint.helper.js.map +1 -0
- package/dist/partner-mcp/helpers/mcpReferenceResolution.helper.d.ts +52 -0
- package/dist/partner-mcp/helpers/mcpReferenceResolution.helper.js +343 -0
- package/dist/partner-mcp/helpers/mcpReferenceResolution.helper.js.map +1 -0
- package/dist/partner-mcp/helpers/partnerErrorSanitization.helper.d.ts +18 -0
- package/dist/partner-mcp/helpers/partnerErrorSanitization.helper.js +63 -0
- package/dist/partner-mcp/helpers/partnerErrorSanitization.helper.js.map +1 -0
- package/dist/partner-mcp/partnerApiClient.d.ts +4 -0
- package/dist/partner-mcp/partnerApiClient.js +38 -1
- package/dist/partner-mcp/partnerApiClient.js.map +1 -1
- package/dist/partner-mcp/tools/definitions.js +233 -12
- package/dist/partner-mcp/tools/definitions.js.map +1 -1
- package/dist/partner-mcp/tools/registerTools.js +107 -23
- package/dist/partner-mcp/tools/registerTools.js.map +1 -1
- package/dist/partner-mcp/tools/schemas.d.ts +40 -0
- package/dist/partner-mcp/tools/schemas.js +55 -0
- package/dist/partner-mcp/tools/schemas.js.map +1 -1
- package/dist/services/credentialStore.service.d.ts +8 -2
- package/dist/services/credentialStore.service.js +22 -10
- package/dist/services/credentialStore.service.js.map +1 -1
- package/dist/services/doctor.service.d.ts +22 -0
- package/dist/services/doctor.service.js +186 -0
- package/dist/services/doctor.service.js.map +1 -0
- package/dist/services/mcpInstall.service.d.ts +43 -0
- package/dist/services/mcpInstall.service.js +117 -0
- package/dist/services/mcpInstall.service.js.map +1 -0
- package/dist/services/mcpLauncher.service.d.ts +2 -0
- package/dist/services/mcpLauncher.service.js +6 -3
- package/dist/services/mcpLauncher.service.js.map +1 -1
- package/dist/services/profileStore.service.d.ts +53 -0
- package/dist/services/profileStore.service.js +129 -0
- package/dist/services/profileStore.service.js.map +1 -0
- package/dist/services/setupPrompt.service.d.ts +25 -0
- package/dist/services/setupPrompt.service.js +40 -0
- package/dist/services/setupPrompt.service.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { CLI_VERSION, DEFAULT_CALLBACK_HOST, DEFAULT_CALLBACK_PATH, DEFAULT_CALLBACK_PORT, DEVELOPER_DOCS_URL, PARTNERS_PORTAL_URL, } from '../constants.js';
|
|
2
|
+
import { PartnerApiClient } from '../partner-mcp/partnerApiClient.js';
|
|
3
|
+
import { toolDefinitions } from '../partner-mcp/tools/definitions.js';
|
|
4
|
+
import { getActiveProfileName, resolveCredentialsFilePath } from './profileStore.service.js';
|
|
5
|
+
import { loadCredentials } from './credentialStore.service.js';
|
|
6
|
+
function appendDoctorCheck(params) {
|
|
7
|
+
params.checks.push({
|
|
8
|
+
checkId: params.checkId,
|
|
9
|
+
label: params.label,
|
|
10
|
+
status: params.status,
|
|
11
|
+
message: params.message,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
export async function runDoctorChecks(params = {}) {
|
|
15
|
+
const { profileName, homeDirectory, fetchImplementation = fetch } = params;
|
|
16
|
+
const checks = [];
|
|
17
|
+
appendDoctorCheck({
|
|
18
|
+
checks,
|
|
19
|
+
checkId: 'cli_version',
|
|
20
|
+
label: 'CLI version',
|
|
21
|
+
status: 'pass',
|
|
22
|
+
message: CLI_VERSION,
|
|
23
|
+
});
|
|
24
|
+
const credentialsFilePath = resolveCredentialsFilePath({ profileName, homeDirectory });
|
|
25
|
+
let activeProfileName = profileName;
|
|
26
|
+
if (!activeProfileName) {
|
|
27
|
+
activeProfileName = await getActiveProfileName({ homeDirectory });
|
|
28
|
+
}
|
|
29
|
+
appendDoctorCheck({
|
|
30
|
+
checks,
|
|
31
|
+
checkId: 'active_profile',
|
|
32
|
+
label: 'Active profile',
|
|
33
|
+
status: 'pass',
|
|
34
|
+
message: activeProfileName,
|
|
35
|
+
});
|
|
36
|
+
appendDoctorCheck({
|
|
37
|
+
checks,
|
|
38
|
+
checkId: 'credentials_path',
|
|
39
|
+
label: 'Credentials file',
|
|
40
|
+
status: 'pass',
|
|
41
|
+
message: credentialsFilePath,
|
|
42
|
+
});
|
|
43
|
+
const credentials = await loadCredentials({ profileName, homeDirectory, configFilePath: credentialsFilePath });
|
|
44
|
+
if (!credentials?.clientId || !credentials.clientSecret) {
|
|
45
|
+
appendDoctorCheck({
|
|
46
|
+
checks,
|
|
47
|
+
checkId: 'partner_credentials',
|
|
48
|
+
label: 'Partner app credentials',
|
|
49
|
+
status: 'fail',
|
|
50
|
+
message: 'Missing client ID or secret. Run `count init` or `count setup`.',
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
appendDoctorCheck({
|
|
55
|
+
checks,
|
|
56
|
+
checkId: 'partner_credentials',
|
|
57
|
+
label: 'Partner app credentials',
|
|
58
|
+
status: 'pass',
|
|
59
|
+
message: `Configured for ${credentials.apiBaseUrl}`,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
const redirectUri = `http://${DEFAULT_CALLBACK_HOST}:${DEFAULT_CALLBACK_PORT}${DEFAULT_CALLBACK_PATH}`;
|
|
63
|
+
appendDoctorCheck({
|
|
64
|
+
checks,
|
|
65
|
+
checkId: 'redirect_uri',
|
|
66
|
+
label: 'OAuth redirect URI',
|
|
67
|
+
status: 'pass',
|
|
68
|
+
message: `${redirectUri} (register at ${PARTNERS_PORTAL_URL})`,
|
|
69
|
+
});
|
|
70
|
+
appendDoctorCheck({
|
|
71
|
+
checks,
|
|
72
|
+
checkId: 'mcp_tools',
|
|
73
|
+
label: 'MCP tool registry',
|
|
74
|
+
status: 'pass',
|
|
75
|
+
message: `${toolDefinitions.length} COUNT_* tools loaded`,
|
|
76
|
+
});
|
|
77
|
+
if (!credentials?.accessToken || !credentials.refreshToken) {
|
|
78
|
+
appendDoctorCheck({
|
|
79
|
+
checks,
|
|
80
|
+
checkId: 'login_tokens',
|
|
81
|
+
label: 'Workspace login',
|
|
82
|
+
status: 'fail',
|
|
83
|
+
message: 'Not logged in. Run `count login`.',
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
const workspaceLabel = credentials.workspaceName ?? credentials.workspaceId ?? 'authenticated workspace';
|
|
88
|
+
appendDoctorCheck({
|
|
89
|
+
checks,
|
|
90
|
+
checkId: 'login_tokens',
|
|
91
|
+
label: 'Workspace login',
|
|
92
|
+
status: 'pass',
|
|
93
|
+
message: workspaceLabel,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
if (credentials?.clientId && credentials.clientSecret) {
|
|
97
|
+
await appendApiConnectivityCheck({
|
|
98
|
+
checks,
|
|
99
|
+
credentials,
|
|
100
|
+
fetchImplementation,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
appendDoctorCheck({
|
|
104
|
+
checks,
|
|
105
|
+
checkId: 'developer_docs',
|
|
106
|
+
label: 'Partner API docs',
|
|
107
|
+
status: 'pass',
|
|
108
|
+
message: DEVELOPER_DOCS_URL,
|
|
109
|
+
});
|
|
110
|
+
const passed = checks.every((_check) => _check.status !== 'fail');
|
|
111
|
+
return { checks, passed };
|
|
112
|
+
}
|
|
113
|
+
async function appendApiConnectivityCheck(params) {
|
|
114
|
+
const { checks, credentials, fetchImplementation } = params;
|
|
115
|
+
try {
|
|
116
|
+
const partnerClient = new PartnerApiClient({
|
|
117
|
+
config: {
|
|
118
|
+
apiBaseUrl: credentials.apiBaseUrl,
|
|
119
|
+
clientId: credentials.clientId,
|
|
120
|
+
clientSecret: credentials.clientSecret,
|
|
121
|
+
accessToken: credentials.accessToken,
|
|
122
|
+
refreshToken: credentials.refreshToken,
|
|
123
|
+
requestTimeoutMs: credentials.requestTimeoutMs,
|
|
124
|
+
},
|
|
125
|
+
fetchImplementation,
|
|
126
|
+
});
|
|
127
|
+
if (credentials.accessToken && credentials.refreshToken) {
|
|
128
|
+
await partnerClient.request({
|
|
129
|
+
method: 'GET',
|
|
130
|
+
path: '/partners/chart-of-accounts',
|
|
131
|
+
query: { limit: 1 },
|
|
132
|
+
requiresUserAuth: true,
|
|
133
|
+
});
|
|
134
|
+
appendDoctorCheck({
|
|
135
|
+
checks,
|
|
136
|
+
checkId: 'api_connectivity',
|
|
137
|
+
label: 'COUNT API connectivity',
|
|
138
|
+
status: 'pass',
|
|
139
|
+
message: `Authenticated request succeeded against ${credentials.apiBaseUrl}`,
|
|
140
|
+
});
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const healthResponse = await fetchImplementation(credentials.apiBaseUrl, { method: 'HEAD' });
|
|
144
|
+
if (healthResponse.ok || healthResponse.status === 404 || healthResponse.status === 405) {
|
|
145
|
+
appendDoctorCheck({
|
|
146
|
+
checks,
|
|
147
|
+
checkId: 'api_connectivity',
|
|
148
|
+
label: 'COUNT API connectivity',
|
|
149
|
+
status: 'warn',
|
|
150
|
+
message: `API host reachable at ${credentials.apiBaseUrl}. Run \`count login\` to verify workspace access.`,
|
|
151
|
+
});
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
appendDoctorCheck({
|
|
155
|
+
checks,
|
|
156
|
+
checkId: 'api_connectivity',
|
|
157
|
+
label: 'COUNT API connectivity',
|
|
158
|
+
status: 'fail',
|
|
159
|
+
message: `API host returned HTTP ${healthResponse.status} for ${credentials.apiBaseUrl}`,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
164
|
+
appendDoctorCheck({
|
|
165
|
+
checks,
|
|
166
|
+
checkId: 'api_connectivity',
|
|
167
|
+
label: 'COUNT API connectivity',
|
|
168
|
+
status: 'fail',
|
|
169
|
+
message,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
export function formatDoctorReport(params) {
|
|
174
|
+
const statusSymbol = {
|
|
175
|
+
pass: '✓',
|
|
176
|
+
warn: '!',
|
|
177
|
+
fail: '✗',
|
|
178
|
+
};
|
|
179
|
+
const lines = params.result.checks.map((_check) => {
|
|
180
|
+
return `${statusSymbol[_check.status]} ${_check.label}: ${_check.message}`;
|
|
181
|
+
});
|
|
182
|
+
lines.push('');
|
|
183
|
+
lines.push(params.result.passed ? 'All required checks passed.' : 'One or more checks failed.');
|
|
184
|
+
return `${lines.join('\n')}\n`;
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=doctor.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.service.js","sourceRoot":"","sources":["../../src/services/doctor.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export declare function resolveCursorMcpConfigPath(params?: {
|
|
2
|
+
homeDirectory?: string;
|
|
3
|
+
}): string;
|
|
4
|
+
export declare function resolveClaudeCodeSettingsPath(params?: {
|
|
5
|
+
homeDirectory?: string;
|
|
6
|
+
}): string;
|
|
7
|
+
export declare function resolveClaudeDesktopConfigPath(params?: {
|
|
8
|
+
homeDirectory?: string;
|
|
9
|
+
}): string;
|
|
10
|
+
export type McpInstallTarget = 'cursor' | 'claude-code' | 'claude-desktop' | 'all';
|
|
11
|
+
export interface McpInstallTargetDefinition {
|
|
12
|
+
targetId: McpInstallTarget;
|
|
13
|
+
label: string;
|
|
14
|
+
configFilePath: string;
|
|
15
|
+
}
|
|
16
|
+
interface ResolveMcpInstallTargetsParams {
|
|
17
|
+
target: McpInstallTarget;
|
|
18
|
+
homeDirectory?: string;
|
|
19
|
+
}
|
|
20
|
+
export declare function resolveMcpInstallTargets(params: ResolveMcpInstallTargetsParams): McpInstallTargetDefinition[];
|
|
21
|
+
interface MergeCountMcpServerConfigParams {
|
|
22
|
+
existingConfiguration: Record<string, unknown>;
|
|
23
|
+
countServerConfiguration: Record<string, unknown>;
|
|
24
|
+
}
|
|
25
|
+
export declare function mergeCountMcpServerConfig(params: MergeCountMcpServerConfigParams): Record<string, unknown>;
|
|
26
|
+
export interface InstallMcpConfigurationParams {
|
|
27
|
+
target: McpInstallTarget;
|
|
28
|
+
homeDirectory?: string;
|
|
29
|
+
dryRun?: boolean;
|
|
30
|
+
}
|
|
31
|
+
export interface InstallMcpConfigurationResult {
|
|
32
|
+
targetId: McpInstallTarget;
|
|
33
|
+
label: string;
|
|
34
|
+
configFilePath: string;
|
|
35
|
+
dryRun: boolean;
|
|
36
|
+
mergedConfiguration: Record<string, unknown>;
|
|
37
|
+
}
|
|
38
|
+
export declare function installMcpConfiguration(params: InstallMcpConfigurationParams): Promise<InstallMcpConfigurationResult[]>;
|
|
39
|
+
interface FormatInstallMcpReportParams {
|
|
40
|
+
installationResults: InstallMcpConfigurationResult[];
|
|
41
|
+
}
|
|
42
|
+
export declare function formatInstallMcpReport(params: FormatInstallMcpReportParams): string;
|
|
43
|
+
export {};
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { buildClaudeCodeMcpConfig } from './mcpLauncher.service.js';
|
|
5
|
+
export function resolveCursorMcpConfigPath(params = {}) {
|
|
6
|
+
return path.join(params.homeDirectory ?? os.homedir(), '.cursor', 'mcp.json');
|
|
7
|
+
}
|
|
8
|
+
export function resolveClaudeCodeSettingsPath(params = {}) {
|
|
9
|
+
return path.join(params.homeDirectory ?? os.homedir(), '.claude', 'settings.json');
|
|
10
|
+
}
|
|
11
|
+
export function resolveClaudeDesktopConfigPath(params = {}) {
|
|
12
|
+
const homeDirectory = params.homeDirectory ?? os.homedir();
|
|
13
|
+
if (process.platform === 'darwin') {
|
|
14
|
+
return path.join(homeDirectory, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
|
|
15
|
+
}
|
|
16
|
+
if (process.platform === 'win32') {
|
|
17
|
+
const applicationDataDirectory = process.env.APPDATA ?? path.join(homeDirectory, 'AppData', 'Roaming');
|
|
18
|
+
return path.join(applicationDataDirectory, 'Claude', 'claude_desktop_config.json');
|
|
19
|
+
}
|
|
20
|
+
return path.join(homeDirectory, '.config', 'Claude', 'claude_desktop_config.json');
|
|
21
|
+
}
|
|
22
|
+
export function resolveMcpInstallTargets(params) {
|
|
23
|
+
const { target, homeDirectory } = params;
|
|
24
|
+
const allTargets = [
|
|
25
|
+
{
|
|
26
|
+
targetId: 'cursor',
|
|
27
|
+
label: 'Cursor',
|
|
28
|
+
configFilePath: resolveCursorMcpConfigPath({ homeDirectory }),
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
targetId: 'claude-code',
|
|
32
|
+
label: 'Claude Code',
|
|
33
|
+
configFilePath: resolveClaudeCodeSettingsPath({ homeDirectory }),
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
targetId: 'claude-desktop',
|
|
37
|
+
label: 'Claude Desktop',
|
|
38
|
+
configFilePath: resolveClaudeDesktopConfigPath({ homeDirectory }),
|
|
39
|
+
},
|
|
40
|
+
];
|
|
41
|
+
if (target === 'all') {
|
|
42
|
+
return allTargets;
|
|
43
|
+
}
|
|
44
|
+
const matchingTarget = allTargets.find((_entry) => _entry.targetId === target);
|
|
45
|
+
if (!matchingTarget) {
|
|
46
|
+
throw new Error(`Unsupported MCP install target "${target}".`);
|
|
47
|
+
}
|
|
48
|
+
return [matchingTarget];
|
|
49
|
+
}
|
|
50
|
+
async function readJsonFile(params) {
|
|
51
|
+
try {
|
|
52
|
+
const rawContents = await fs.readFile(params.filePath, 'utf8');
|
|
53
|
+
const parsedJson = JSON.parse(rawContents);
|
|
54
|
+
if (!parsedJson || typeof parsedJson !== 'object' || Array.isArray(parsedJson)) {
|
|
55
|
+
return {};
|
|
56
|
+
}
|
|
57
|
+
return parsedJson;
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
if (error && typeof error === 'object' && 'code' in error && error.code === 'ENOENT') {
|
|
61
|
+
return {};
|
|
62
|
+
}
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export function mergeCountMcpServerConfig(params) {
|
|
67
|
+
const existingMcpServers = params.existingConfiguration.mcpServers && typeof params.existingConfiguration.mcpServers === 'object'
|
|
68
|
+
? params.existingConfiguration.mcpServers
|
|
69
|
+
: {};
|
|
70
|
+
return {
|
|
71
|
+
...params.existingConfiguration,
|
|
72
|
+
mcpServers: {
|
|
73
|
+
...existingMcpServers,
|
|
74
|
+
count: params.countServerConfiguration,
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
export async function installMcpConfiguration(params) {
|
|
79
|
+
const { target, homeDirectory, dryRun = false } = params;
|
|
80
|
+
const installTargets = resolveMcpInstallTargets({ target, homeDirectory });
|
|
81
|
+
const countMcpConfiguration = buildClaudeCodeMcpConfig();
|
|
82
|
+
const countServerConfiguration = countMcpConfiguration.mcpServers.count;
|
|
83
|
+
const installationResults = [];
|
|
84
|
+
for (const installTarget of installTargets) {
|
|
85
|
+
const existingConfiguration = await readJsonFile({ filePath: installTarget.configFilePath });
|
|
86
|
+
const mergedConfiguration = mergeCountMcpServerConfig({
|
|
87
|
+
existingConfiguration,
|
|
88
|
+
countServerConfiguration,
|
|
89
|
+
});
|
|
90
|
+
if (!dryRun) {
|
|
91
|
+
await fs.mkdir(path.dirname(installTarget.configFilePath), { recursive: true });
|
|
92
|
+
await fs.writeFile(installTarget.configFilePath, `${JSON.stringify(mergedConfiguration, null, 2)}\n`, {
|
|
93
|
+
encoding: 'utf8',
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
installationResults.push({
|
|
97
|
+
targetId: installTarget.targetId,
|
|
98
|
+
label: installTarget.label,
|
|
99
|
+
configFilePath: installTarget.configFilePath,
|
|
100
|
+
dryRun,
|
|
101
|
+
mergedConfiguration,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
return installationResults;
|
|
105
|
+
}
|
|
106
|
+
export function formatInstallMcpReport(params) {
|
|
107
|
+
const lines = [];
|
|
108
|
+
for (const installationResult of params.installationResults) {
|
|
109
|
+
const actionLabel = installationResult.dryRun ? 'Would install MCP config for' : 'Installed MCP config for';
|
|
110
|
+
lines.push(`${actionLabel} ${installationResult.label}`);
|
|
111
|
+
lines.push(` ${installationResult.configFilePath}`);
|
|
112
|
+
}
|
|
113
|
+
lines.push('');
|
|
114
|
+
lines.push('Restart your editor or reload MCP servers to pick up the change.');
|
|
115
|
+
return `${lines.join('\n')}\n`;
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=mcpInstall.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcpInstall.service.js","sourceRoot":"","sources":["../../src/services/mcpInstall.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import type { CountCliCredentials } from '../types.js';
|
|
2
2
|
interface BuildMcpEnvironmentParams {
|
|
3
3
|
credentials: CountCliCredentials;
|
|
4
|
+
credentialsFilePath?: string;
|
|
4
5
|
}
|
|
5
6
|
export declare function buildMcpEnvironment(params: BuildMcpEnvironmentParams): NodeJS.ProcessEnv;
|
|
6
7
|
export declare function resolvePartnerMcpEntryPath(): string;
|
|
7
8
|
export declare function resolveCliEntryPath(): string;
|
|
8
9
|
interface LaunchPartnerMcpServerParams {
|
|
9
10
|
credentials: CountCliCredentials;
|
|
11
|
+
credentialsFilePath?: string;
|
|
10
12
|
}
|
|
11
13
|
export declare function launchPartnerMcpServer(params: LaunchPartnerMcpServerParams): Promise<number>;
|
|
12
14
|
export declare function buildClaudeCodeMcpConfig(): Record<string, unknown>;
|
|
@@ -3,7 +3,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
3
3
|
import { spawn } from 'node:child_process';
|
|
4
4
|
import { getConfigFilePath } from './credentialStore.service.js';
|
|
5
5
|
export function buildMcpEnvironment(params) {
|
|
6
|
-
const { credentials } = params;
|
|
6
|
+
const { credentials, credentialsFilePath } = params;
|
|
7
7
|
return {
|
|
8
8
|
...process.env,
|
|
9
9
|
COUNT_API_URL: credentials.apiBaseUrl,
|
|
@@ -12,7 +12,7 @@ export function buildMcpEnvironment(params) {
|
|
|
12
12
|
COUNT_ACCESS_TOKEN: credentials.accessToken ?? '',
|
|
13
13
|
COUNT_REFRESH_TOKEN: credentials.refreshToken ?? '',
|
|
14
14
|
COUNT_REQUEST_TIMEOUT_MS: String(credentials.requestTimeoutMs),
|
|
15
|
-
COUNT_CREDENTIALS_FILE: getConfigFilePath(),
|
|
15
|
+
COUNT_CREDENTIALS_FILE: credentialsFilePath ?? getConfigFilePath(),
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
18
|
export function resolvePartnerMcpEntryPath() {
|
|
@@ -25,7 +25,10 @@ export function resolveCliEntryPath() {
|
|
|
25
25
|
}
|
|
26
26
|
export async function launchPartnerMcpServer(params) {
|
|
27
27
|
const entryPath = resolvePartnerMcpEntryPath();
|
|
28
|
-
const environment = buildMcpEnvironment({
|
|
28
|
+
const environment = buildMcpEnvironment({
|
|
29
|
+
credentials: params.credentials,
|
|
30
|
+
credentialsFilePath: params.credentialsFilePath,
|
|
31
|
+
});
|
|
29
32
|
return await new Promise((resolve, reject) => {
|
|
30
33
|
const childProcess = spawn(process.execPath, [entryPath], {
|
|
31
34
|
env: environment,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcpLauncher.service.js","sourceRoot":"","sources":["../../src/services/mcpLauncher.service.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"mcpLauncher.service.js","sourceRoot":"","sources":["../../src/services/mcpLauncher.service.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAOjE,MAAM,UAAU,mBAAmB,CAAC,MAAiC;IACnE,MAAM,EAAE,WAAW,EAAE,mBAAmB,EAAE,GAAG,MAAM,CAAC;IAEpD,OAAO;QACL,GAAG,OAAO,CAAC,GAAG;QACd,aAAa,EAAE,WAAW,CAAC,UAAU;QACrC,eAAe,EAAE,WAAW,CAAC,QAAQ;QACrC,mBAAmB,EAAE,WAAW,CAAC,YAAY;QAC7C,kBAAkB,EAAE,WAAW,CAAC,WAAW,IAAI,EAAE;QACjD,mBAAmB,EAAE,WAAW,CAAC,YAAY,IAAI,EAAE;QACnD,wBAAwB,EAAE,MAAM,CAAC,WAAW,CAAC,gBAAgB,CAAC;QAC9D,sBAAsB,EAAE,mBAAmB,IAAI,iBAAiB,EAAE;KACnE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,0BAA0B;IACxC,MAAM,oBAAoB,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1E,OAAO,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,yBAAyB,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,MAAM,oBAAoB,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1E,OAAO,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,aAAa,CAAC,CAAC;AACxD,CAAC;AAOD,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,MAAoC;IAC/E,MAAM,SAAS,GAAG,0BAA0B,EAAE,CAAC;IAC/C,MAAM,WAAW,GAAG,mBAAmB,CAAC;QACtC,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,mBAAmB,EAAE,MAAM,CAAC,mBAAmB;KAChD,CAAC,CAAC;IAEH,OAAO,MAAM,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACnD,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,SAAS,CAAC,EAAE;YACxD,GAAG,EAAE,WAAW;YAChB,KAAK,EAAE,SAAS;SACjB,CAAC,CAAC;QAEH,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACnC,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE;YAC7C,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,CAAC,IAAI,KAAK,CAAC,yCAAyC,MAAM,GAAG,CAAC,CAAC,CAAC;gBACtE,OAAO;YACT,CAAC;YAED,OAAO,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,wBAAwB;IACtC,OAAO;QACL,UAAU,EAAE;YACV,KAAK,EAAE;gBACL,OAAO,EAAE,OAAO,CAAC,QAAQ;gBACzB,IAAI,EAAE,CAAC,mBAAmB,EAAE,EAAE,KAAK,CAAC;aACrC;SACF;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export declare const DEFAULT_PROFILE_NAME = "default";
|
|
2
|
+
export declare const ACTIVE_PROFILE_FILE_NAME = "active-profile";
|
|
3
|
+
export declare const PROFILES_DIRECTORY_NAME = "profiles";
|
|
4
|
+
interface GetConfigDirectoryPathParams {
|
|
5
|
+
homeDirectory?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function getConfigDirectoryPath(params?: GetConfigDirectoryPathParams): string;
|
|
8
|
+
interface GetActiveProfileFilePathParams {
|
|
9
|
+
homeDirectory?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function getActiveProfileFilePath(params?: GetActiveProfileFilePathParams): string;
|
|
12
|
+
interface GetProfilesDirectoryPathParams {
|
|
13
|
+
homeDirectory?: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function getProfilesDirectoryPath(params?: GetProfilesDirectoryPathParams): string;
|
|
16
|
+
interface GetProfileCredentialsFilePathParams {
|
|
17
|
+
profileName: string;
|
|
18
|
+
homeDirectory?: string;
|
|
19
|
+
}
|
|
20
|
+
export declare function getProfileCredentialsFilePath(params: GetProfileCredentialsFilePathParams): string;
|
|
21
|
+
interface GetLegacyCredentialsFilePathParams {
|
|
22
|
+
homeDirectory?: string;
|
|
23
|
+
}
|
|
24
|
+
export declare function getLegacyCredentialsFilePath(params?: GetLegacyCredentialsFilePathParams): string;
|
|
25
|
+
interface ResolveCredentialsFilePathParams {
|
|
26
|
+
profileName?: string;
|
|
27
|
+
homeDirectory?: string;
|
|
28
|
+
}
|
|
29
|
+
export declare function resolveCredentialsFilePath(params?: ResolveCredentialsFilePathParams): string;
|
|
30
|
+
interface GetActiveProfileNameParams {
|
|
31
|
+
homeDirectory?: string;
|
|
32
|
+
}
|
|
33
|
+
export declare function getActiveProfileName(params?: GetActiveProfileNameParams): Promise<string>;
|
|
34
|
+
interface SetActiveProfileNameParams {
|
|
35
|
+
profileName: string;
|
|
36
|
+
homeDirectory?: string;
|
|
37
|
+
}
|
|
38
|
+
export declare function setActiveProfileName(params: SetActiveProfileNameParams): Promise<void>;
|
|
39
|
+
interface ListProfileNamesParams {
|
|
40
|
+
homeDirectory?: string;
|
|
41
|
+
}
|
|
42
|
+
export declare function listProfileNames(params?: ListProfileNamesParams): Promise<string[]>;
|
|
43
|
+
interface EnsureProfileDirectoryParams {
|
|
44
|
+
profileName: string;
|
|
45
|
+
homeDirectory?: string;
|
|
46
|
+
}
|
|
47
|
+
export declare function ensureProfileDirectory(params: EnsureProfileDirectoryParams): Promise<string>;
|
|
48
|
+
interface MigrateLegacyCredentialsToProfileParams {
|
|
49
|
+
profileName?: string;
|
|
50
|
+
homeDirectory?: string;
|
|
51
|
+
}
|
|
52
|
+
export declare function migrateLegacyCredentialsToProfile(params?: MigrateLegacyCredentialsToProfileParams): Promise<boolean>;
|
|
53
|
+
export {};
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import fsPromises from 'node:fs/promises';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { DEFAULT_CONFIG_DIRECTORY_NAME, DEFAULT_CONFIG_FILE_NAME } from '../constants.js';
|
|
6
|
+
export const DEFAULT_PROFILE_NAME = 'default';
|
|
7
|
+
export const ACTIVE_PROFILE_FILE_NAME = 'active-profile';
|
|
8
|
+
export const PROFILES_DIRECTORY_NAME = 'profiles';
|
|
9
|
+
export function getConfigDirectoryPath(params = {}) {
|
|
10
|
+
const { homeDirectory = os.homedir() } = params;
|
|
11
|
+
return path.join(homeDirectory, DEFAULT_CONFIG_DIRECTORY_NAME);
|
|
12
|
+
}
|
|
13
|
+
export function getActiveProfileFilePath(params = {}) {
|
|
14
|
+
return path.join(getConfigDirectoryPath(params), ACTIVE_PROFILE_FILE_NAME);
|
|
15
|
+
}
|
|
16
|
+
export function getProfilesDirectoryPath(params = {}) {
|
|
17
|
+
return path.join(getConfigDirectoryPath(params), PROFILES_DIRECTORY_NAME);
|
|
18
|
+
}
|
|
19
|
+
export function getProfileCredentialsFilePath(params) {
|
|
20
|
+
const { profileName, homeDirectory } = params;
|
|
21
|
+
return path.join(getProfilesDirectoryPath({ homeDirectory }), profileName, DEFAULT_CONFIG_FILE_NAME);
|
|
22
|
+
}
|
|
23
|
+
export function getLegacyCredentialsFilePath(params = {}) {
|
|
24
|
+
return path.join(getConfigDirectoryPath(params), DEFAULT_CONFIG_FILE_NAME);
|
|
25
|
+
}
|
|
26
|
+
function profileModeIsActive(params) {
|
|
27
|
+
const { homeDirectory } = params;
|
|
28
|
+
const configDirectory = getConfigDirectoryPath({ homeDirectory });
|
|
29
|
+
const activeProfileFilePath = path.join(configDirectory, ACTIVE_PROFILE_FILE_NAME);
|
|
30
|
+
const profilesDirectory = path.join(configDirectory, PROFILES_DIRECTORY_NAME);
|
|
31
|
+
if (fs.existsSync(activeProfileFilePath)) {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
if (!fs.existsSync(profilesDirectory)) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
const profileDirectoryEntries = fs.readdirSync(profilesDirectory, { withFileTypes: true });
|
|
39
|
+
return profileDirectoryEntries.some((_entry) => _entry.isDirectory() && fs.existsSync(getProfileCredentialsFilePath({ profileName: _entry.name, homeDirectory })));
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export function resolveCredentialsFilePath(params = {}) {
|
|
46
|
+
const { profileName, homeDirectory } = params;
|
|
47
|
+
if (profileName) {
|
|
48
|
+
return getProfileCredentialsFilePath({ profileName, homeDirectory });
|
|
49
|
+
}
|
|
50
|
+
if (profileModeIsActive({ homeDirectory })) {
|
|
51
|
+
const activeProfileName = readActiveProfileNameSync({ homeDirectory });
|
|
52
|
+
return getProfileCredentialsFilePath({ profileName: activeProfileName, homeDirectory });
|
|
53
|
+
}
|
|
54
|
+
return getLegacyCredentialsFilePath({ homeDirectory });
|
|
55
|
+
}
|
|
56
|
+
function readActiveProfileNameSync(params = {}) {
|
|
57
|
+
const activeProfileFilePath = getActiveProfileFilePath(params);
|
|
58
|
+
try {
|
|
59
|
+
const profileName = fs.readFileSync(activeProfileFilePath, 'utf8').trim();
|
|
60
|
+
if (profileName) {
|
|
61
|
+
return profileName;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// Fall through to default profile name.
|
|
66
|
+
}
|
|
67
|
+
return DEFAULT_PROFILE_NAME;
|
|
68
|
+
}
|
|
69
|
+
export async function getActiveProfileName(params = {}) {
|
|
70
|
+
if (!profileModeIsActive(params)) {
|
|
71
|
+
return DEFAULT_PROFILE_NAME;
|
|
72
|
+
}
|
|
73
|
+
return readActiveProfileNameSync(params);
|
|
74
|
+
}
|
|
75
|
+
export async function setActiveProfileName(params) {
|
|
76
|
+
const { profileName, homeDirectory } = params;
|
|
77
|
+
const configDirectory = getConfigDirectoryPath({ homeDirectory });
|
|
78
|
+
const activeProfileFilePath = getActiveProfileFilePath({ homeDirectory });
|
|
79
|
+
await fsPromises.mkdir(configDirectory, { recursive: true, mode: 0o700 });
|
|
80
|
+
await fsPromises.writeFile(activeProfileFilePath, `${profileName.trim()}\n`, { encoding: 'utf8', mode: 0o600 });
|
|
81
|
+
}
|
|
82
|
+
export async function listProfileNames(params = {}) {
|
|
83
|
+
const { homeDirectory } = params;
|
|
84
|
+
const profileNameSet = new Set();
|
|
85
|
+
const profilesDirectory = getProfilesDirectoryPath({ homeDirectory });
|
|
86
|
+
if (fs.existsSync(profilesDirectory)) {
|
|
87
|
+
const profileDirectoryEntries = await fsPromises.readdir(profilesDirectory, { withFileTypes: true });
|
|
88
|
+
for (const profileDirectoryEntry of profileDirectoryEntries) {
|
|
89
|
+
if (!profileDirectoryEntry.isDirectory()) {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
const profileCredentialsFilePath = getProfileCredentialsFilePath({
|
|
93
|
+
profileName: profileDirectoryEntry.name,
|
|
94
|
+
homeDirectory,
|
|
95
|
+
});
|
|
96
|
+
if (fs.existsSync(profileCredentialsFilePath)) {
|
|
97
|
+
profileNameSet.add(profileDirectoryEntry.name);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
const legacyCredentialsFilePath = getLegacyCredentialsFilePath({ homeDirectory });
|
|
102
|
+
if (fs.existsSync(legacyCredentialsFilePath) && !profileModeIsActive({ homeDirectory })) {
|
|
103
|
+
profileNameSet.add(DEFAULT_PROFILE_NAME);
|
|
104
|
+
}
|
|
105
|
+
return [...profileNameSet].sort();
|
|
106
|
+
}
|
|
107
|
+
export async function ensureProfileDirectory(params) {
|
|
108
|
+
const { profileName, homeDirectory } = params;
|
|
109
|
+
const profileDirectoryPath = path.join(getProfilesDirectoryPath({ homeDirectory }), profileName);
|
|
110
|
+
await fsPromises.mkdir(profileDirectoryPath, { recursive: true, mode: 0o700 });
|
|
111
|
+
return profileDirectoryPath;
|
|
112
|
+
}
|
|
113
|
+
export async function migrateLegacyCredentialsToProfile(params = {}) {
|
|
114
|
+
const profileName = params.profileName ?? DEFAULT_PROFILE_NAME;
|
|
115
|
+
const { homeDirectory } = params;
|
|
116
|
+
const legacyCredentialsFilePath = getLegacyCredentialsFilePath({ homeDirectory });
|
|
117
|
+
const profileCredentialsFilePath = getProfileCredentialsFilePath({ profileName, homeDirectory });
|
|
118
|
+
if (!fs.existsSync(legacyCredentialsFilePath)) {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
if (fs.existsSync(profileCredentialsFilePath)) {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
await ensureProfileDirectory({ profileName, homeDirectory });
|
|
125
|
+
await fsPromises.copyFile(legacyCredentialsFilePath, profileCredentialsFilePath);
|
|
126
|
+
await setActiveProfileName({ profileName, homeDirectory });
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=profileStore.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profileStore.service.js","sourceRoot":"","sources":["../../src/services/profileStore.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as readline from 'node:readline/promises';
|
|
2
|
+
export interface PromptLineParams {
|
|
3
|
+
readlineInterface: readline.Interface;
|
|
4
|
+
question: string;
|
|
5
|
+
defaultValue?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function promptLine(params: PromptLineParams): Promise<string>;
|
|
8
|
+
export interface PromptYesNoParams {
|
|
9
|
+
readlineInterface: readline.Interface;
|
|
10
|
+
question: string;
|
|
11
|
+
defaultYes?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare function promptYesNo(params: PromptYesNoParams): Promise<boolean>;
|
|
14
|
+
export interface CreatePromptInterfaceParams {
|
|
15
|
+
inputStream?: NodeJS.ReadableStream;
|
|
16
|
+
outputStream?: NodeJS.WritableStream;
|
|
17
|
+
}
|
|
18
|
+
export declare function createPromptInterface(params?: CreatePromptInterfaceParams): readline.Interface;
|
|
19
|
+
export interface PromptChoiceParams {
|
|
20
|
+
readlineInterface: readline.Interface;
|
|
21
|
+
question: string;
|
|
22
|
+
choices: string[];
|
|
23
|
+
defaultChoice?: string;
|
|
24
|
+
}
|
|
25
|
+
export declare function promptChoice(params: PromptChoiceParams): Promise<string>;
|