@kodycodes/cli 0.0.0 → 1.0.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.
@@ -0,0 +1,19 @@
1
+ export const defaultMcpUrl = 'https://kody.codes/mcp';
2
+ /** Pin to Kody's stateless `/mcp` lane. */
3
+ export const modernMcpProtocolVersion = '2026-07-28';
4
+ export const defaultScopes = ['profile', 'email'];
5
+ export const keyringService = 'kody.codes';
6
+ export const loginTimeoutMs = 5 * 60 * 1000;
7
+ export const accessTokenSkewMs = 60_000;
8
+ export const cliName = '@kodycodes/cli';
9
+ export const cliClientUri = 'https://github.com/kody-bot/cli';
10
+ /** Fixed loopback port so CIMD can list an exact redirect URI. */
11
+ export const oauthCallbackPort = 43742;
12
+ export const cliClientIdMetadataPath = '/oauth/cli-client-metadata.json';
13
+ export function cliClientMetadataUrl(mcpUrl) {
14
+ return new URL(cliClientIdMetadataPath, mcpUrl).href;
15
+ }
16
+ export function cliRedirectUrl(port = oauthCallbackPort) {
17
+ return new URL(`http://127.0.0.1:${port}/callback`);
18
+ }
19
+ //# sourceMappingURL=defaults.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.js","sourceRoot":"","sources":["../src/defaults.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,aAAa,GAAG,wBAAwB,CAAA;AACrD,2CAA2C;AAC3C,MAAM,CAAC,MAAM,wBAAwB,GAAG,YAAY,CAAA;AACpD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,SAAS,EAAE,OAAO,CAAU,CAAA;AAC1D,MAAM,CAAC,MAAM,cAAc,GAAG,YAAY,CAAA;AAC1C,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAA;AAC3C,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAA;AACvC,MAAM,CAAC,MAAM,OAAO,GAAG,gBAAgB,CAAA;AACvC,MAAM,CAAC,MAAM,YAAY,GAAG,iCAAiC,CAAA;AAC7D,kEAAkE;AAClE,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,CAAA;AACtC,MAAM,CAAC,MAAM,uBAAuB,GAAG,iCAAiC,CAAA;AAExE,MAAM,UAAU,oBAAoB,CAAC,MAAc;IAClD,OAAO,IAAI,GAAG,CAAC,uBAAuB,EAAE,MAAM,CAAC,CAAC,IAAI,CAAA;AACrD,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAe,iBAAiB;IAC9D,OAAO,IAAI,GAAG,CAAC,oBAAoB,IAAI,WAAW,CAAC,CAAA;AACpD,CAAC"}
package/dist/help.d.ts ADDED
@@ -0,0 +1 @@
1
+ export declare const usage: string;
package/dist/help.js ADDED
@@ -0,0 +1,19 @@
1
+ import { defaultMcpUrl } from './defaults.js';
2
+ import { readPackageVersion } from './package-info.js';
3
+ export const usage = `Kody CLI ${readPackageVersion()}
4
+
5
+ A local MCP client for https://kody.codes — login once, then search and execute.
6
+
7
+ Usage:
8
+ kody login [--mcp-url <url>] [--no-browser]
9
+ kody logout [--mcp-url <url>]
10
+ kody status [--mcp-url <url>]
11
+ kody whoami [--mcp-url <url>] [--json]
12
+ kody search [query] [--entity <ref>] [--domain <id>] [--limit <n>] [--json]
13
+ kody execute [--code <esm>] [--file <path>] [--params <json>] [--conversation-id <id>] [--json]
14
+ kody skill install [--project]
15
+
16
+ Environment:
17
+ KODY_MCP_URL Override the default MCP URL (${defaultMcpUrl})
18
+ `;
19
+ //# sourceMappingURL=help.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help.js","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAEtD,MAAM,CAAC,MAAM,KAAK,GAAG,YAAY,kBAAkB,EAAE;;;;;;;;;;;;;;iDAcJ,aAAa;CAC7D,CAAA"}
package/dist/mcp.d.ts ADDED
@@ -0,0 +1,27 @@
1
+ import type { SecretBackend } from './store.js';
2
+ export type CallToolInput = {
3
+ name: 'search' | 'execute';
4
+ args: Record<string, unknown>;
5
+ mcpUrl?: string;
6
+ backend?: SecretBackend;
7
+ fetchFn?: typeof fetch;
8
+ };
9
+ export type ToolCallResult = {
10
+ content: Array<{
11
+ type: string;
12
+ text?: string;
13
+ [key: string]: unknown;
14
+ }>;
15
+ structuredContent?: unknown;
16
+ isError?: boolean;
17
+ };
18
+ export declare function callKodyTool(input: CallToolInput): Promise<ToolCallResult>;
19
+ export declare function listKodyTools(input: {
20
+ mcpUrl?: string;
21
+ backend?: SecretBackend;
22
+ fetchFn?: typeof fetch;
23
+ }): Promise<Array<{
24
+ name: string;
25
+ description?: string;
26
+ }>>;
27
+ export declare function formatToolResult(result: ToolCallResult, json: boolean): string;
package/dist/mcp.js ADDED
@@ -0,0 +1,104 @@
1
+ import { Client, StreamableHTTPClientTransport, UnauthorizedError, } from '@modelcontextprotocol/client';
2
+ import { cliName, modernMcpProtocolVersion } from './defaults.js';
3
+ import { ensureFreshCredentials, refreshStoredCredentials } from './auth.js';
4
+ import { readPackageVersion } from './package-info.js';
5
+ import { redactError } from './redact.js';
6
+ async function connect(mcpUrl, accessToken, fetchFn) {
7
+ const transport = new StreamableHTTPClientTransport(new URL(mcpUrl), {
8
+ requestInit: {
9
+ headers: {
10
+ Authorization: `Bearer ${accessToken}`,
11
+ },
12
+ },
13
+ ...(fetchFn ? { fetch: fetchFn } : {}),
14
+ });
15
+ const client = new Client({
16
+ name: cliName,
17
+ version: readPackageVersion(),
18
+ }, { versionNegotiation: { mode: { pin: modernMcpProtocolVersion } } });
19
+ await client.connect(transport);
20
+ return { client, transport };
21
+ }
22
+ export async function callKodyTool(input) {
23
+ const credentials = await ensureFreshCredentials({
24
+ mcpUrl: input.mcpUrl,
25
+ backend: input.backend,
26
+ fetchFn: input.fetchFn,
27
+ });
28
+ try {
29
+ return await invoke(credentials.mcpUrl, credentials.accessToken, input);
30
+ }
31
+ catch (error) {
32
+ if (!(error instanceof UnauthorizedError) && !isUnauthorized(error)) {
33
+ throw redactError(error);
34
+ }
35
+ const refreshed = await refreshStoredCredentials({
36
+ credentials,
37
+ backend: input.backend,
38
+ fetchFn: input.fetchFn,
39
+ });
40
+ try {
41
+ return await invoke(refreshed.mcpUrl, refreshed.accessToken, input);
42
+ }
43
+ catch (retryError) {
44
+ throw redactError(retryError);
45
+ }
46
+ }
47
+ }
48
+ async function invoke(mcpUrl, accessToken, input) {
49
+ const { client, transport } = await connect(mcpUrl, accessToken, input.fetchFn);
50
+ try {
51
+ const result = await client.callTool({
52
+ name: input.name,
53
+ arguments: input.args,
54
+ });
55
+ return result;
56
+ }
57
+ finally {
58
+ await transport.close().catch(() => undefined);
59
+ }
60
+ }
61
+ export async function listKodyTools(input) {
62
+ const credentials = await ensureFreshCredentials({
63
+ mcpUrl: input.mcpUrl,
64
+ backend: input.backend,
65
+ fetchFn: input.fetchFn,
66
+ });
67
+ const { client, transport } = await connect(credentials.mcpUrl, credentials.accessToken, input.fetchFn);
68
+ try {
69
+ const listed = await client.listTools();
70
+ return listed.tools.map((tool) => ({
71
+ name: tool.name,
72
+ description: tool.description,
73
+ }));
74
+ }
75
+ finally {
76
+ await transport.close().catch(() => undefined);
77
+ }
78
+ }
79
+ export function formatToolResult(result, json) {
80
+ if (json) {
81
+ return `${JSON.stringify({
82
+ isError: result.isError ?? false,
83
+ structuredContent: result.structuredContent ?? null,
84
+ content: result.content,
85
+ }, null, 2)}\n`;
86
+ }
87
+ const texts = result.content
88
+ .filter((part) => part.type === 'text' && typeof part.text === 'string')
89
+ .map((part) => part.text ?? '');
90
+ if (texts.length > 0)
91
+ return texts.join('\n\n').replace(/\n*$/, '\n');
92
+ if (result.structuredContent != null) {
93
+ return `${JSON.stringify(result.structuredContent, null, 2)}\n`;
94
+ }
95
+ return `${JSON.stringify(result.content, null, 2)}\n`;
96
+ }
97
+ function isUnauthorized(error) {
98
+ if (!error || typeof error !== 'object')
99
+ return false;
100
+ const status = 'code' in error ? error.code : undefined;
101
+ return (status === 401 ||
102
+ (error instanceof Error && /401|unauthorized/i.test(error.message)));
103
+ }
104
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { type OAuthClientMetadata, type OAuthClientProvider } from '@modelcontextprotocol/client';
2
+ import type { StoredCredentials } from './store.js';
3
+ export declare function buildCliClientMetadata(): OAuthClientMetadata;
4
+ export declare function createCliOAuthProvider(input: {
5
+ mcpUrl: string;
6
+ redirectUri: URL;
7
+ existing?: StoredCredentials;
8
+ loadStoredTokens: boolean;
9
+ openBrowser: boolean;
10
+ expectedState: string;
11
+ onAuthorizationUrl?: (url: URL) => void;
12
+ }): OAuthClientProvider;
@@ -0,0 +1,89 @@
1
+ import { validateClientMetadataUrl, } from '@modelcontextprotocol/client';
2
+ import { cliClientMetadataUrl, cliClientUri, cliName, cliRedirectUrl, defaultScopes, } from './defaults.js';
3
+ import { openUrl } from './open-url.js';
4
+ export function buildCliClientMetadata() {
5
+ return {
6
+ client_name: cliName,
7
+ client_uri: cliClientUri,
8
+ redirect_uris: [cliRedirectUrl().href],
9
+ grant_types: ['authorization_code', 'refresh_token'],
10
+ response_types: ['code'],
11
+ token_endpoint_auth_method: 'none',
12
+ application_type: 'native',
13
+ scope: defaultScopes.join(' '),
14
+ };
15
+ }
16
+ export function createCliOAuthProvider(input) {
17
+ const clientMetadataUrl = cliClientMetadataUrl(input.mcpUrl);
18
+ validateClientMetadataUrl(clientMetadataUrl);
19
+ let codeVerifier = '';
20
+ let discoveryState;
21
+ // Always present a CIMD client_id. Leaving this empty would let the SDK
22
+ // fall back to deprecated dynamic client registration.
23
+ let clientInformation = input.existing
24
+ ? {
25
+ client_id: input.existing.clientId,
26
+ ...(input.existing.clientSecret
27
+ ? { client_secret: input.existing.clientSecret }
28
+ : {}),
29
+ issuer: input.existing.authorizationServerUrl,
30
+ }
31
+ : { client_id: clientMetadataUrl };
32
+ let tokens = input.loadStoredTokens && input.existing
33
+ ? {
34
+ access_token: input.existing.accessToken,
35
+ token_type: input.existing.tokenType,
36
+ ...(input.existing.refreshToken
37
+ ? { refresh_token: input.existing.refreshToken }
38
+ : {}),
39
+ ...(input.existing.scope ? { scope: input.existing.scope } : {}),
40
+ issuer: input.existing.authorizationServerUrl,
41
+ }
42
+ : undefined;
43
+ return {
44
+ clientMetadataUrl,
45
+ get redirectUrl() {
46
+ return input.redirectUri;
47
+ },
48
+ get clientMetadata() {
49
+ return buildCliClientMetadata();
50
+ },
51
+ state() {
52
+ return input.expectedState;
53
+ },
54
+ clientInformation() {
55
+ return clientInformation;
56
+ },
57
+ saveClientInformation(next) {
58
+ clientInformation = next;
59
+ },
60
+ tokens() {
61
+ return tokens;
62
+ },
63
+ saveTokens(next) {
64
+ tokens = next;
65
+ },
66
+ async redirectToAuthorization(authorizationUrl) {
67
+ input.onAuthorizationUrl?.(authorizationUrl);
68
+ if (input.openBrowser) {
69
+ await openUrl(authorizationUrl.href);
70
+ }
71
+ },
72
+ saveCodeVerifier(next) {
73
+ codeVerifier = next;
74
+ },
75
+ codeVerifier() {
76
+ if (!codeVerifier) {
77
+ throw new Error('OAuth PKCE verifier is missing.');
78
+ }
79
+ return codeVerifier;
80
+ },
81
+ saveDiscoveryState(next) {
82
+ discoveryState = next;
83
+ },
84
+ discoveryState() {
85
+ return discoveryState;
86
+ },
87
+ };
88
+ }
89
+ //# sourceMappingURL=oauth-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-provider.js","sourceRoot":"","sources":["../src/oauth-provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function openUrl(url: string): Promise<boolean>;
@@ -0,0 +1,21 @@
1
+ import { spawn } from 'node:child_process';
2
+ export async function openUrl(url) {
3
+ const platform = process.platform;
4
+ const command = platform === 'darwin'
5
+ ? 'open'
6
+ : platform === 'win32'
7
+ ? 'cmd'
8
+ : 'xdg-open';
9
+ const args = platform === 'win32' ? ['/c', 'start', '', url] : [url];
10
+ return await new Promise((resolve) => {
11
+ const child = spawn(command, args, {
12
+ detached: true,
13
+ stdio: 'ignore',
14
+ windowsHide: true,
15
+ });
16
+ child.on('error', () => resolve(false));
17
+ child.unref();
18
+ resolve(true);
19
+ });
20
+ }
21
+ //# sourceMappingURL=open-url.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open-url.js","sourceRoot":"","sources":["../src/open-url.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAE1C,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,GAAW;IACxC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAA;IACjC,MAAM,OAAO,GACZ,QAAQ,KAAK,QAAQ;QACpB,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,QAAQ,KAAK,OAAO;YACrB,CAAC,CAAC,KAAK;YACP,CAAC,CAAC,UAAU,CAAA;IACf,MAAM,IAAI,GAAG,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;IACpE,OAAO,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QACpC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE;YAClC,QAAQ,EAAE,IAAI;YACd,KAAK,EAAE,QAAQ;YACf,WAAW,EAAE,IAAI;SACjB,CAAC,CAAA;QACF,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAA;QACvC,KAAK,CAAC,KAAK,EAAE,CAAA;QACb,OAAO,CAAC,IAAI,CAAC,CAAA;IACd,CAAC,CAAC,CAAA;AACH,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function readPackageVersion(): string;
@@ -0,0 +1,7 @@
1
+ import { createRequire } from 'node:module';
2
+ const require = createRequire(import.meta.url);
3
+ export function readPackageVersion() {
4
+ const pkg = require('../package.json');
5
+ return pkg.version ?? '0.0.0';
6
+ }
7
+ //# sourceMappingURL=package-info.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-info.js","sourceRoot":"","sources":["../src/package-info.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE3C,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAE9C,MAAM,UAAU,kBAAkB;IACjC,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAyB,CAAA;IAC9D,OAAO,GAAG,CAAC,OAAO,IAAI,OAAO,CAAA;AAC9B,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function redact(value: string): string;
2
+ export declare function redactError(error: unknown): Error;
package/dist/redact.js ADDED
@@ -0,0 +1,12 @@
1
+ const secretPattern = /(access_token|refresh_token|client_secret|authorization)["']?\s*[:=]\s*["']?[^\s"',}]+/gi;
2
+ export function redact(value) {
3
+ return value.replace(secretPattern, '$1=[redacted]');
4
+ }
5
+ export function redactError(error) {
6
+ if (error instanceof Error) {
7
+ error.message = redact(error.message);
8
+ return error;
9
+ }
10
+ return new Error(redact(String(error)));
11
+ }
12
+ //# sourceMappingURL=redact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact.js","sourceRoot":"","sources":["../src/redact.ts"],"names":[],"mappings":"AAAA,MAAM,aAAa,GAClB,0FAA0F,CAAA;AAE3F,MAAM,UAAU,MAAM,CAAC,KAAa;IACnC,OAAO,KAAK,CAAC,OAAO,CAAC,aAAa,EAAE,eAAe,CAAC,CAAA;AACrD,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAc;IACzC,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC5B,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QACrC,OAAO,KAAK,CAAA;IACb,CAAC;IACD,OAAO,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;AACxC,CAAC"}
@@ -0,0 +1,18 @@
1
+ export declare function bundledSkillPath(): string;
2
+ export declare function userSkillTargets(home?: string): Array<{
3
+ host: string;
4
+ path: string;
5
+ }>;
6
+ export declare function projectSkillTargets(cwd?: string): Array<{
7
+ host: string;
8
+ path: string;
9
+ }>;
10
+ export declare function installSkill(input: {
11
+ project?: boolean;
12
+ cwd?: string;
13
+ home?: string;
14
+ sourcePath?: string;
15
+ }): Promise<Array<{
16
+ host: string;
17
+ path: string;
18
+ }>>;
package/dist/skill.js ADDED
@@ -0,0 +1,35 @@
1
+ import { mkdir, readFile, writeFile } from 'node:fs/promises';
2
+ import { dirname, join } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { homedir } from 'node:os';
5
+ const skillRelativePath = 'skills/kody/SKILL.md';
6
+ export function bundledSkillPath() {
7
+ return join(fileURLToPath(new URL('../', import.meta.url)), skillRelativePath);
8
+ }
9
+ export function userSkillTargets(home = homedir()) {
10
+ return [
11
+ { host: 'Claude Code', path: join(home, '.claude', 'skills', 'kody', 'SKILL.md') },
12
+ { host: 'Cursor', path: join(home, '.cursor', 'skills', 'kody', 'SKILL.md') },
13
+ { host: 'Agents', path: join(home, '.agents', 'skills', 'kody', 'SKILL.md') },
14
+ ];
15
+ }
16
+ export function projectSkillTargets(cwd = process.cwd()) {
17
+ return [
18
+ { host: 'Agents', path: join(cwd, '.agents', 'skills', 'kody', 'SKILL.md') },
19
+ { host: 'Cursor', path: join(cwd, '.cursor', 'skills', 'kody', 'SKILL.md') },
20
+ { host: 'Claude Code', path: join(cwd, '.claude', 'skills', 'kody', 'SKILL.md') },
21
+ ];
22
+ }
23
+ export async function installSkill(input) {
24
+ const source = input.sourcePath ?? bundledSkillPath();
25
+ const body = await readFile(source, 'utf8');
26
+ const targets = input.project
27
+ ? projectSkillTargets(input.cwd)
28
+ : userSkillTargets(input.home);
29
+ for (const target of targets) {
30
+ await mkdir(dirname(target.path), { recursive: true });
31
+ await writeFile(target.path, body, 'utf8');
32
+ }
33
+ return targets;
34
+ }
35
+ //# sourceMappingURL=skill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill.js","sourceRoot":"","sources":["../src/skill.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC7D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAEjC,MAAM,iBAAiB,GAAG,sBAAsB,CAAA;AAEhD,MAAM,UAAU,gBAAgB;IAC/B,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAA;AAC/E,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,OAAe,OAAO,EAAE;IAIxD,OAAO;QACN,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE;QAClF,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE;QAC7E,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE;KAC7E,CAAA;AACF,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IAI9D,OAAO;QACN,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE;QAC5E,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE;QAC5E,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE;KACjF,CAAA;AACF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,KAKlC;IACA,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,IAAI,gBAAgB,EAAE,CAAA;IACrD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO;QAC5B,CAAC,CAAC,mBAAmB,CAAC,KAAK,CAAC,GAAG,CAAC;QAChC,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAC/B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC9B,MAAM,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QACtD,MAAM,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;IAC3C,CAAC;IACD,OAAO,OAAO,CAAA;AACf,CAAC"}
@@ -0,0 +1,34 @@
1
+ export type StoredCredentials = {
2
+ version: 1;
3
+ mcpUrl: string;
4
+ resource: string;
5
+ authorizationServerUrl: string;
6
+ clientId: string;
7
+ clientSecret?: string;
8
+ accessToken: string;
9
+ refreshToken?: string;
10
+ tokenType: string;
11
+ expiresAt?: number;
12
+ scope?: string;
13
+ };
14
+ export type SecretBackend = {
15
+ kind: 'keyring' | 'file';
16
+ path?: string;
17
+ get(): string | null;
18
+ set(value: string): void;
19
+ delete(): boolean;
20
+ };
21
+ export declare function accountForMcpUrl(mcpUrl: string): string;
22
+ export declare function fileStorePath(mcpUrl: string, home?: string): string;
23
+ export declare function createFileBackend(path: string): SecretBackend;
24
+ export declare function createKeyringBackend(mcpUrl: string): SecretBackend;
25
+ export declare function resolveBackend(mcpUrl: string, preferred?: SecretBackend): SecretBackend;
26
+ export declare function parseCredentials(raw: string): StoredCredentials;
27
+ export declare function loadCredentials(mcpUrl?: string, backend?: SecretBackend): StoredCredentials | null;
28
+ export declare function saveCredentials(credentials: StoredCredentials, backend?: SecretBackend): {
29
+ backend: SecretBackend;
30
+ };
31
+ export declare function deleteCredentials(mcpUrl?: string, backend?: SecretBackend): {
32
+ deleted: boolean;
33
+ backend: SecretBackend;
34
+ };
package/dist/store.js ADDED
@@ -0,0 +1,140 @@
1
+ import { chmodSync, mkdirSync, readFileSync, unlinkSync, writeFileSync, } from 'node:fs';
2
+ import { dirname, join } from 'node:path';
3
+ import { homedir } from 'node:os';
4
+ import { Entry } from '@napi-rs/keyring';
5
+ import { defaultMcpUrl, keyringService } from './defaults.js';
6
+ export function accountForMcpUrl(mcpUrl) {
7
+ return `cli:${new URL(mcpUrl).origin}`;
8
+ }
9
+ export function fileStorePath(mcpUrl, home = homedir()) {
10
+ const origin = new URL(mcpUrl).host.replace(/[^a-zA-Z0-9.-]/g, '_');
11
+ const base = process.platform === 'win32'
12
+ ? join(process.env.APPDATA || join(home, 'AppData', 'Roaming'), 'kody')
13
+ : process.platform === 'darwin'
14
+ ? join(home, 'Library', 'Application Support', 'kody')
15
+ : join(process.env.XDG_CONFIG_HOME || join(home, '.config'), 'kody');
16
+ return join(base, `credentials-${origin}.json`);
17
+ }
18
+ export function createFileBackend(path) {
19
+ return {
20
+ kind: 'file',
21
+ path,
22
+ get() {
23
+ try {
24
+ return readFileSync(path, 'utf8');
25
+ }
26
+ catch {
27
+ return null;
28
+ }
29
+ },
30
+ set(value) {
31
+ mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
32
+ writeFileSync(path, value, { mode: 0o600 });
33
+ try {
34
+ chmodSync(path, 0o600);
35
+ }
36
+ catch {
37
+ // Windows cannot apply POSIX modes.
38
+ }
39
+ },
40
+ delete() {
41
+ try {
42
+ unlinkSync(path);
43
+ return true;
44
+ }
45
+ catch {
46
+ return false;
47
+ }
48
+ },
49
+ };
50
+ }
51
+ export function createKeyringBackend(mcpUrl) {
52
+ const entry = new Entry(keyringService, accountForMcpUrl(mcpUrl));
53
+ return {
54
+ kind: 'keyring',
55
+ get() {
56
+ try {
57
+ return entry.getPassword();
58
+ }
59
+ catch {
60
+ return null;
61
+ }
62
+ },
63
+ set(value) {
64
+ entry.setPassword(value);
65
+ },
66
+ delete() {
67
+ try {
68
+ return entry.deleteCredential();
69
+ }
70
+ catch {
71
+ return false;
72
+ }
73
+ },
74
+ };
75
+ }
76
+ export function resolveBackend(mcpUrl, preferred) {
77
+ if (preferred)
78
+ return preferred;
79
+ try {
80
+ return createKeyringBackend(mcpUrl);
81
+ }
82
+ catch {
83
+ return createFileBackend(fileStorePath(mcpUrl));
84
+ }
85
+ }
86
+ export function parseCredentials(raw) {
87
+ const parsed = JSON.parse(raw);
88
+ if (parsed.version !== 1 || !parsed.accessToken || !parsed.clientId) {
89
+ throw new Error('Stored Kody credentials are invalid. Run `kody login`.');
90
+ }
91
+ return parsed;
92
+ }
93
+ export function loadCredentials(mcpUrl = defaultMcpUrl, backend) {
94
+ const store = resolveBackend(mcpUrl, backend);
95
+ try {
96
+ const raw = store.get();
97
+ if (!raw)
98
+ return null;
99
+ return parseCredentials(raw);
100
+ }
101
+ catch (error) {
102
+ if (store.kind === 'keyring' && !backend) {
103
+ const fallback = createFileBackend(fileStorePath(mcpUrl));
104
+ const raw = fallback.get();
105
+ return raw ? parseCredentials(raw) : null;
106
+ }
107
+ throw error;
108
+ }
109
+ }
110
+ export function saveCredentials(credentials, backend) {
111
+ const store = resolveBackend(credentials.mcpUrl, backend);
112
+ try {
113
+ store.set(JSON.stringify(credentials));
114
+ return { backend: store };
115
+ }
116
+ catch (error) {
117
+ if (store.kind === 'keyring' && !backend) {
118
+ const fallback = createFileBackend(fileStorePath(credentials.mcpUrl));
119
+ fallback.set(JSON.stringify(credentials));
120
+ return { backend: fallback };
121
+ }
122
+ throw error;
123
+ }
124
+ }
125
+ export function deleteCredentials(mcpUrl = defaultMcpUrl, backend) {
126
+ const store = resolveBackend(mcpUrl, backend);
127
+ let deleted = false;
128
+ try {
129
+ deleted = store.delete();
130
+ }
131
+ catch {
132
+ deleted = false;
133
+ }
134
+ if (store.kind === 'keyring' && !backend) {
135
+ const file = createFileBackend(fileStorePath(mcpUrl));
136
+ deleted = file.delete() || deleted;
137
+ }
138
+ return { deleted, backend: store };
139
+ }
140
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,SAAS,EACT,SAAS,EACT,YAAY,EACZ,UAAU,EACV,aAAa,GACb,MAAM,SAAS,CAAA;AAChB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AACxC,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAwB7D,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC9C,OAAO,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAA;AACvC,CAAC;AAED,MAAM,UAAU,aAAa,CAC5B,MAAc,EACd,OAAe,OAAO,EAAE;IAExB,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAA;IACnE,MAAM,IAAI,GACT,OAAO,CAAC,QAAQ,KAAK,OAAO;QAC3B,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QACvE,CAAC,CAAC,OAAO,CAAC,QAAQ,KAAK,QAAQ;YAC9B,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,CAAC;YACtD,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,MAAM,CAAC,CAAA;IACvE,OAAO,IAAI,CAAC,IAAI,EAAE,eAAe,MAAM,OAAO,CAAC,CAAA;AAChD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC7C,OAAO;QACN,IAAI,EAAE,MAAM;QACZ,IAAI;QACJ,GAAG;YACF,IAAI,CAAC;gBACJ,OAAO,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;YAClC,CAAC;YAAC,MAAM,CAAC;gBACR,OAAO,IAAI,CAAA;YACZ,CAAC;QACF,CAAC;QACD,GAAG,CAAC,KAAa;YAChB,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;YAC1D,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;YAC3C,IAAI,CAAC;gBACJ,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;YACvB,CAAC;YAAC,MAAM,CAAC;gBACR,oCAAoC;YACrC,CAAC;QACF,CAAC;QACD,MAAM;YACL,IAAI,CAAC;gBACJ,UAAU,CAAC,IAAI,CAAC,CAAA;gBAChB,OAAO,IAAI,CAAA;YACZ,CAAC;YAAC,MAAM,CAAC;gBACR,OAAO,KAAK,CAAA;YACb,CAAC;QACF,CAAC;KACD,CAAA;AACF,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAc;IAClD,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,cAAc,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAA;IACjE,OAAO;QACN,IAAI,EAAE,SAAS;QACf,GAAG;YACF,IAAI,CAAC;gBACJ,OAAO,KAAK,CAAC,WAAW,EAAE,CAAA;YAC3B,CAAC;YAAC,MAAM,CAAC;gBACR,OAAO,IAAI,CAAA;YACZ,CAAC;QACF,CAAC;QACD,GAAG,CAAC,KAAa;YAChB,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;QACzB,CAAC;QACD,MAAM;YACL,IAAI,CAAC;gBACJ,OAAO,KAAK,CAAC,gBAAgB,EAAE,CAAA;YAChC,CAAC;YAAC,MAAM,CAAC;gBACR,OAAO,KAAK,CAAA;YACb,CAAC;QACF,CAAC;KACD,CAAA;AACF,CAAC;AAED,MAAM,UAAU,cAAc,CAC7B,MAAc,EACd,SAAyB;IAEzB,IAAI,SAAS;QAAE,OAAO,SAAS,CAAA;IAC/B,IAAI,CAAC;QACJ,OAAO,oBAAoB,CAAC,MAAM,CAAC,CAAA;IACpC,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,iBAAiB,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAA;IAChD,CAAC;AACF,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAsB,CAAA;IACnD,IAAI,MAAM,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QACrE,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAA;IAC1E,CAAC;IACD,OAAO,MAAM,CAAA;AACd,CAAC;AAED,MAAM,UAAU,eAAe,CAC9B,SAAiB,aAAa,EAC9B,OAAuB;IAEvB,MAAM,KAAK,GAAG,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC7C,IAAI,CAAC;QACJ,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,EAAE,CAAA;QACvB,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAA;QACrB,OAAO,gBAAgB,CAAC,GAAG,CAAC,CAAA;IAC7B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,OAAO,EAAE,CAAC;YAC1C,MAAM,QAAQ,GAAG,iBAAiB,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAA;YACzD,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAA;YAC1B,OAAO,GAAG,CAAC,CAAC,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QAC1C,CAAC;QACD,MAAM,KAAK,CAAA;IACZ,CAAC;AACF,CAAC;AAED,MAAM,UAAU,eAAe,CAC9B,WAA8B,EAC9B,OAAuB;IAEvB,MAAM,KAAK,GAAG,cAAc,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACzD,IAAI,CAAC;QACJ,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAA;QACtC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAA;IAC1B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,OAAO,EAAE,CAAC;YAC1C,MAAM,QAAQ,GAAG,iBAAiB,CAAC,aAAa,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAA;YACrE,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAA;YACzC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAA;QAC7B,CAAC;QACD,MAAM,KAAK,CAAA;IACZ,CAAC;AACF,CAAC;AAED,MAAM,UAAU,iBAAiB,CAChC,SAAiB,aAAa,EAC9B,OAAuB;IAEvB,MAAM,KAAK,GAAG,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC7C,IAAI,OAAO,GAAG,KAAK,CAAA;IACnB,IAAI,CAAC;QACJ,OAAO,GAAG,KAAK,CAAC,MAAM,EAAE,CAAA;IACzB,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,GAAG,KAAK,CAAA;IAChB,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,OAAO,EAAE,CAAC;QAC1C,MAAM,IAAI,GAAG,iBAAiB,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAA;QACrD,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,OAAO,CAAA;IACnC,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAA;AACnC,CAAC"}