openkitt 0.1.2
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 +236 -0
- package/dist/ast/engine.d.ts +26 -0
- package/dist/ast/engine.js +130 -0
- package/dist/ast/engine.js.map +1 -0
- package/dist/ast/operations.d.ts +13 -0
- package/dist/ast/operations.js +329 -0
- package/dist/ast/operations.js.map +1 -0
- package/dist/ast/validator.d.ts +19 -0
- package/dist/ast/validator.js +281 -0
- package/dist/ast/validator.js.map +1 -0
- package/dist/audit/logger.d.ts +14 -0
- package/dist/audit/logger.js +102 -0
- package/dist/audit/logger.js.map +1 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.js +401 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/create-confirm.d.ts +13 -0
- package/dist/commands/create-confirm.js +38 -0
- package/dist/commands/create-confirm.js.map +1 -0
- package/dist/commands/create-infra.d.ts +20 -0
- package/dist/commands/create-infra.js +63 -0
- package/dist/commands/create-infra.js.map +1 -0
- package/dist/commands/create-manifest.d.ts +10 -0
- package/dist/commands/create-manifest.js +21 -0
- package/dist/commands/create-manifest.js.map +1 -0
- package/dist/commands/create-packages.d.ts +17 -0
- package/dist/commands/create-packages.js +69 -0
- package/dist/commands/create-packages.js.map +1 -0
- package/dist/commands/create-pipeline.d.ts +15 -0
- package/dist/commands/create-pipeline.js +57 -0
- package/dist/commands/create-pipeline.js.map +1 -0
- package/dist/commands/create-scaffolding.d.ts +12 -0
- package/dist/commands/create-scaffolding.js +137 -0
- package/dist/commands/create-scaffolding.js.map +1 -0
- package/dist/commands/create-staging.d.ts +13 -0
- package/dist/commands/create-staging.js +17 -0
- package/dist/commands/create-staging.js.map +1 -0
- package/dist/commands/create-transforms.d.ts +10 -0
- package/dist/commands/create-transforms.js +33 -0
- package/dist/commands/create-transforms.js.map +1 -0
- package/dist/commands/create.d.ts +2 -0
- package/dist/commands/create.js +155 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/delete.d.ts +2 -0
- package/dist/commands/delete.js +83 -0
- package/dist/commands/delete.js.map +1 -0
- package/dist/commands/deploy.d.ts +5 -0
- package/dist/commands/deploy.js +371 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/domain.d.ts +2 -0
- package/dist/commands/domain.js +90 -0
- package/dist/commands/domain.js.map +1 -0
- package/dist/commands/env.d.ts +2 -0
- package/dist/commands/env.js +153 -0
- package/dist/commands/env.js.map +1 -0
- package/dist/commands/help.d.ts +3 -0
- package/dist/commands/help.js +107 -0
- package/dist/commands/help.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.js +217 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/list.d.ts +2 -0
- package/dist/commands/list.js +142 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/login.d.ts +2 -0
- package/dist/commands/login.js +235 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logs.d.ts +2 -0
- package/dist/commands/logs.js +90 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/publish.d.ts +2 -0
- package/dist/commands/publish.js +113 -0
- package/dist/commands/publish.js.map +1 -0
- package/dist/commands/run.d.ts +14 -0
- package/dist/commands/run.js +196 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/settings.d.ts +3 -0
- package/dist/commands/settings.js +278 -0
- package/dist/commands/settings.js.map +1 -0
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.js +88 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/versions.d.ts +2 -0
- package/dist/commands/versions.js +242 -0
- package/dist/commands/versions.js.map +1 -0
- package/dist/credentials/config.d.ts +12 -0
- package/dist/credentials/config.js +196 -0
- package/dist/credentials/config.js.map +1 -0
- package/dist/credentials/encryption.d.ts +9 -0
- package/dist/credentials/encryption.js +100 -0
- package/dist/credentials/encryption.js.map +1 -0
- package/dist/credentials/keychain.d.ts +8 -0
- package/dist/credentials/keychain.js +236 -0
- package/dist/credentials/keychain.js.map +1 -0
- package/dist/credentials/railway.d.ts +9 -0
- package/dist/credentials/railway.js +69 -0
- package/dist/credentials/railway.js.map +1 -0
- package/dist/llm/client.d.ts +59 -0
- package/dist/llm/client.js +530 -0
- package/dist/llm/client.js.map +1 -0
- package/dist/llm/operations.d.ts +39 -0
- package/dist/llm/operations.js +131 -0
- package/dist/llm/operations.js.map +1 -0
- package/dist/llm/rate-limiter.d.ts +20 -0
- package/dist/llm/rate-limiter.js +57 -0
- package/dist/llm/rate-limiter.js.map +1 -0
- package/dist/llm/scaffolding.d.ts +51 -0
- package/dist/llm/scaffolding.js +118 -0
- package/dist/llm/scaffolding.js.map +1 -0
- package/dist/manifest/drift.d.ts +6 -0
- package/dist/manifest/drift.js +45 -0
- package/dist/manifest/drift.js.map +1 -0
- package/dist/manifest/reader.d.ts +12 -0
- package/dist/manifest/reader.js +99 -0
- package/dist/manifest/reader.js.map +1 -0
- package/dist/manifest/types.d.ts +31 -0
- package/dist/manifest/types.js +2 -0
- package/dist/manifest/types.js.map +1 -0
- package/dist/manifest/writer.d.ts +9 -0
- package/dist/manifest/writer.js +142 -0
- package/dist/manifest/writer.js.map +1 -0
- package/dist/mcp/client.d.ts +21 -0
- package/dist/mcp/client.js +213 -0
- package/dist/mcp/client.js.map +1 -0
- package/dist/mcp/lifecycle.d.ts +12 -0
- package/dist/mcp/lifecycle.js +149 -0
- package/dist/mcp/lifecycle.js.map +1 -0
- package/dist/mcp/project-guard.d.ts +14 -0
- package/dist/mcp/project-guard.js +27 -0
- package/dist/mcp/project-guard.js.map +1 -0
- package/dist/prompts/operations.d.ts +1 -0
- package/dist/prompts/operations.js +160 -0
- package/dist/prompts/operations.js.map +1 -0
- package/dist/prompts/scaffolding.d.ts +1 -0
- package/dist/prompts/scaffolding.js +331 -0
- package/dist/prompts/scaffolding.js.map +1 -0
- package/dist/prompts/version.d.ts +2 -0
- package/dist/prompts/version.js +3 -0
- package/dist/prompts/version.js.map +1 -0
- package/dist/sandbox/command-allowlist.d.ts +6 -0
- package/dist/sandbox/command-allowlist.js +103 -0
- package/dist/sandbox/command-allowlist.js.map +1 -0
- package/dist/sandbox/package-allowlist.d.ts +6 -0
- package/dist/sandbox/package-allowlist.js +49 -0
- package/dist/sandbox/package-allowlist.js.map +1 -0
- package/dist/sandbox/scanner.d.ts +25 -0
- package/dist/sandbox/scanner.js +196 -0
- package/dist/sandbox/scanner.js.map +1 -0
- package/dist/sandbox/staging.d.ts +12 -0
- package/dist/sandbox/staging.js +107 -0
- package/dist/sandbox/staging.js.map +1 -0
- package/dist/scaffold/frameworks/express.d.ts +3 -0
- package/dist/scaffold/frameworks/express.js +242 -0
- package/dist/scaffold/frameworks/express.js.map +1 -0
- package/dist/scaffold/frameworks/hono.d.ts +3 -0
- package/dist/scaffold/frameworks/hono.js +238 -0
- package/dist/scaffold/frameworks/hono.js.map +1 -0
- package/dist/scaffold/frameworks/nextjs.d.ts +3 -0
- package/dist/scaffold/frameworks/nextjs.js +447 -0
- package/dist/scaffold/frameworks/nextjs.js.map +1 -0
- package/dist/scaffold/frameworks/tanstack-start.d.ts +3 -0
- package/dist/scaffold/frameworks/tanstack-start.js +280 -0
- package/dist/scaffold/frameworks/tanstack-start.js.map +1 -0
- package/dist/scaffold/index.d.ts +4 -0
- package/dist/scaffold/index.js +138 -0
- package/dist/scaffold/index.js.map +1 -0
- package/dist/scaffold/integrations/backend.d.ts +3 -0
- package/dist/scaffold/integrations/backend.js +403 -0
- package/dist/scaffold/integrations/backend.js.map +1 -0
- package/dist/scaffold/integrations/posthog.d.ts +2 -0
- package/dist/scaffold/integrations/posthog.js +21 -0
- package/dist/scaffold/integrations/posthog.js.map +1 -0
- package/dist/scaffold/integrations/sentry.d.ts +2 -0
- package/dist/scaffold/integrations/sentry.js +16 -0
- package/dist/scaffold/integrations/sentry.js.map +1 -0
- package/dist/scaffold/integrations/storybook.d.ts +2 -0
- package/dist/scaffold/integrations/storybook.js +79 -0
- package/dist/scaffold/integrations/storybook.js.map +1 -0
- package/dist/scaffold/integrations/vitest.d.ts +2 -0
- package/dist/scaffold/integrations/vitest.js +37 -0
- package/dist/scaffold/integrations/vitest.js.map +1 -0
- package/dist/scaffold/package-builder.d.ts +3 -0
- package/dist/scaffold/package-builder.js +136 -0
- package/dist/scaffold/package-builder.js.map +1 -0
- package/dist/scaffold/packages.d.ts +4 -0
- package/dist/scaffold/packages.js +144 -0
- package/dist/scaffold/packages.js.map +1 -0
- package/dist/scaffold/types.d.ts +20 -0
- package/dist/scaffold/types.js +2 -0
- package/dist/scaffold/types.js.map +1 -0
- package/dist/types.d.ts +11 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/auth-guard.d.ts +5 -0
- package/dist/utils/auth-guard.js +52 -0
- package/dist/utils/auth-guard.js.map +1 -0
- package/dist/utils/cleanup.d.ts +2 -0
- package/dist/utils/cleanup.js +37 -0
- package/dist/utils/cleanup.js.map +1 -0
- package/dist/utils/constraints.d.ts +11 -0
- package/dist/utils/constraints.js +162 -0
- package/dist/utils/constraints.js.map +1 -0
- package/dist/utils/display.d.ts +32 -0
- package/dist/utils/display.js +103 -0
- package/dist/utils/display.js.map +1 -0
- package/dist/utils/global-config.d.ts +8 -0
- package/dist/utils/global-config.js +39 -0
- package/dist/utils/global-config.js.map +1 -0
- package/dist/utils/pm.d.ts +4 -0
- package/dist/utils/pm.js +40 -0
- package/dist/utils/pm.js.map +1 -0
- package/dist/utils/prerequisites.d.ts +9 -0
- package/dist/utils/prerequisites.js +96 -0
- package/dist/utils/prerequisites.js.map +1 -0
- package/dist/utils/prompts.d.ts +25 -0
- package/dist/utils/prompts.js +148 -0
- package/dist/utils/prompts.js.map +1 -0
- package/dist/utils/validation.d.ts +9 -0
- package/dist/utils/validation.js +38 -0
- package/dist/utils/validation.js.map +1 -0
- package/dist/versions/compat.d.ts +13 -0
- package/dist/versions/compat.js +127 -0
- package/dist/versions/compat.js.map +1 -0
- package/dist/versions/integrity.d.ts +9 -0
- package/dist/versions/integrity.js +60 -0
- package/dist/versions/integrity.js.map +1 -0
- package/dist/versions/parser.d.ts +13 -0
- package/dist/versions/parser.js +106 -0
- package/dist/versions/parser.js.map +1 -0
- package/dist/versions/registry.d.ts +30 -0
- package/dist/versions/registry.js +165 -0
- package/dist/versions/registry.js.map +1 -0
- package/package.json +58 -0
- package/scripts/publish.sh +254 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type LlmProvider = 'anthropic' | 'openai' | 'gemini';
|
|
2
|
+
export interface LlmConfig {
|
|
3
|
+
provider: LlmProvider;
|
|
4
|
+
model: string;
|
|
5
|
+
validatedAt: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function storeLlmCredentials(provider: LlmProvider, model: string, apiKey: string): Promise<void>;
|
|
8
|
+
export declare function getLlmApiKey(): Promise<string | null>;
|
|
9
|
+
export declare function getLlmConfig(): Promise<LlmConfig | null>;
|
|
10
|
+
export declare function updateLlmModel(model: string): Promise<void>;
|
|
11
|
+
export declare function clearLlmCredentials(): Promise<void>;
|
|
12
|
+
export declare function isLlmConfigured(): Promise<boolean>;
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, statSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { homedir, platform } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { decrypt, encrypt } from './encryption.js';
|
|
5
|
+
import { deleteKeychainValue, getKeychainValue, isKeychainAvailable, setKeychainValue, } from './keychain.js';
|
|
6
|
+
const CONFIG_DIR = join(homedir(), '.kitt');
|
|
7
|
+
const CONFIG_FILE = join(CONFIG_DIR, 'config.json');
|
|
8
|
+
const KEYCHAIN_API_KEY = 'llm-api-key';
|
|
9
|
+
const DIR_MODE = 0o700;
|
|
10
|
+
const FILE_MODE = 0o600;
|
|
11
|
+
function isWindows() {
|
|
12
|
+
return platform() === 'win32';
|
|
13
|
+
}
|
|
14
|
+
function hasExtraPermissionBits(actualMode, allowedMode) {
|
|
15
|
+
const activeBits = actualMode & 0o777;
|
|
16
|
+
return (activeBits & ~allowedMode) !== 0;
|
|
17
|
+
}
|
|
18
|
+
function ensurePermissions(path, mode) {
|
|
19
|
+
if (isWindows() || !existsSync(path)) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const currentMode = statSync(path).mode;
|
|
23
|
+
if (hasExtraPermissionBits(currentMode, mode)) {
|
|
24
|
+
console.warn(`[kitt] Detected permissive config permissions for ${path}. Auto-fixing.`);
|
|
25
|
+
chmodSync(path, mode);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function ensureConfigDir() {
|
|
29
|
+
if (!existsSync(CONFIG_DIR)) {
|
|
30
|
+
mkdirSync(CONFIG_DIR, { recursive: true, mode: DIR_MODE });
|
|
31
|
+
}
|
|
32
|
+
if (!isWindows()) {
|
|
33
|
+
ensurePermissions(CONFIG_DIR, DIR_MODE);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function readConfig() {
|
|
37
|
+
ensureConfigDir();
|
|
38
|
+
if (!existsSync(CONFIG_FILE)) {
|
|
39
|
+
return {};
|
|
40
|
+
}
|
|
41
|
+
if (!isWindows()) {
|
|
42
|
+
ensurePermissions(CONFIG_FILE, FILE_MODE);
|
|
43
|
+
}
|
|
44
|
+
const raw = readFileSync(CONFIG_FILE, 'utf-8').trim();
|
|
45
|
+
if (raw.length === 0) {
|
|
46
|
+
return {};
|
|
47
|
+
}
|
|
48
|
+
const parsed = JSON.parse(raw);
|
|
49
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
50
|
+
return {};
|
|
51
|
+
}
|
|
52
|
+
return parsed;
|
|
53
|
+
}
|
|
54
|
+
function writeConfig(config) {
|
|
55
|
+
ensureConfigDir();
|
|
56
|
+
const tempFile = `${CONFIG_FILE}.tmp-${process.pid}-${Date.now()}`;
|
|
57
|
+
const payload = `${JSON.stringify(config, null, 2)}\n`;
|
|
58
|
+
try {
|
|
59
|
+
writeFileSync(tempFile, payload, { encoding: 'utf-8', mode: FILE_MODE });
|
|
60
|
+
if (!isWindows()) {
|
|
61
|
+
chmodSync(tempFile, FILE_MODE);
|
|
62
|
+
}
|
|
63
|
+
renameSync(tempFile, CONFIG_FILE);
|
|
64
|
+
if (!isWindows()) {
|
|
65
|
+
chmodSync(CONFIG_FILE, FILE_MODE);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
if (existsSync(tempFile)) {
|
|
70
|
+
unlinkSync(tempFile);
|
|
71
|
+
}
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function isStoredProvider(value) {
|
|
76
|
+
return value === 'anthropic' || value === 'openai' || value === 'gemini';
|
|
77
|
+
}
|
|
78
|
+
function getStoredLlm(config) {
|
|
79
|
+
const llm = config.llm;
|
|
80
|
+
if (!llm || typeof llm !== 'object') {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
if (!isStoredProvider(llm.provider)) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
if (typeof llm.model !== 'string' || llm.model.length === 0) {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
if (typeof llm.validatedAt !== 'string' || llm.validatedAt.length === 0) {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
if (llm.storage !== 'keychain' && llm.storage !== 'encrypted') {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
return llm;
|
|
96
|
+
}
|
|
97
|
+
export async function storeLlmCredentials(provider, model, apiKey) {
|
|
98
|
+
const validatedAt = new Date().toISOString();
|
|
99
|
+
const keychainAvailable = await isKeychainAvailable();
|
|
100
|
+
if (keychainAvailable) {
|
|
101
|
+
const result = await setKeychainValue(KEYCHAIN_API_KEY, apiKey);
|
|
102
|
+
if (result.success) {
|
|
103
|
+
writeConfig({
|
|
104
|
+
llm: {
|
|
105
|
+
provider,
|
|
106
|
+
model,
|
|
107
|
+
validatedAt,
|
|
108
|
+
storage: 'keychain',
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const encrypted = await encrypt(apiKey);
|
|
115
|
+
await deleteKeychainValue(KEYCHAIN_API_KEY);
|
|
116
|
+
writeConfig({
|
|
117
|
+
llm: {
|
|
118
|
+
provider,
|
|
119
|
+
model,
|
|
120
|
+
validatedAt,
|
|
121
|
+
storage: 'encrypted',
|
|
122
|
+
apiKey: encrypted.encrypted,
|
|
123
|
+
iv: encrypted.iv,
|
|
124
|
+
salt: encrypted.salt,
|
|
125
|
+
authTag: encrypted.authTag,
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
export async function getLlmApiKey() {
|
|
130
|
+
const config = readConfig();
|
|
131
|
+
const llm = getStoredLlm(config);
|
|
132
|
+
if (!llm) {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
if (llm.storage === 'keychain') {
|
|
136
|
+
return getKeychainValue(KEYCHAIN_API_KEY);
|
|
137
|
+
}
|
|
138
|
+
if (typeof llm.apiKey !== 'string' ||
|
|
139
|
+
typeof llm.iv !== 'string' ||
|
|
140
|
+
typeof llm.salt !== 'string' ||
|
|
141
|
+
typeof llm.authTag !== 'string') {
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
try {
|
|
145
|
+
return await decrypt({
|
|
146
|
+
encrypted: llm.apiKey,
|
|
147
|
+
iv: llm.iv,
|
|
148
|
+
salt: llm.salt,
|
|
149
|
+
authTag: llm.authTag,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
export async function getLlmConfig() {
|
|
157
|
+
const config = readConfig();
|
|
158
|
+
const llm = getStoredLlm(config);
|
|
159
|
+
if (!llm) {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
provider: llm.provider,
|
|
164
|
+
model: llm.model,
|
|
165
|
+
validatedAt: llm.validatedAt,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
export async function updateLlmModel(model) {
|
|
169
|
+
const config = readConfig();
|
|
170
|
+
const llm = getStoredLlm(config);
|
|
171
|
+
if (!llm) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
writeConfig({
|
|
175
|
+
...config,
|
|
176
|
+
llm: {
|
|
177
|
+
...llm,
|
|
178
|
+
model,
|
|
179
|
+
},
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
export async function clearLlmCredentials() {
|
|
183
|
+
await deleteKeychainValue(KEYCHAIN_API_KEY);
|
|
184
|
+
const config = readConfig();
|
|
185
|
+
if (!config.llm) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
const nextConfig = { ...config };
|
|
189
|
+
delete nextConfig.llm;
|
|
190
|
+
writeConfig(nextConfig);
|
|
191
|
+
}
|
|
192
|
+
export async function isLlmConfigured() {
|
|
193
|
+
const [apiKey, llmConfig] = await Promise.all([getLlmApiKey(), getLlmConfig()]);
|
|
194
|
+
return apiKey !== null && llmConfig !== null;
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/credentials/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface EncryptedData {
|
|
2
|
+
encrypted: string;
|
|
3
|
+
iv: string;
|
|
4
|
+
salt: string;
|
|
5
|
+
authTag: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function getMachineId(): string;
|
|
8
|
+
export declare function encrypt(plaintext: string): Promise<EncryptedData>;
|
|
9
|
+
export declare function decrypt(data: EncryptedData): Promise<string>;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { execSync } from 'node:child_process';
|
|
2
|
+
import { createCipheriv, createDecipheriv, pbkdf2Sync, randomBytes, } from 'node:crypto';
|
|
3
|
+
import { readFileSync } from 'node:fs';
|
|
4
|
+
import { hostname, platform, userInfo } from 'node:os';
|
|
5
|
+
const KITT_SALT = 'openkitt-credential-salt-v1';
|
|
6
|
+
const PBKDF2_ITERATIONS = 100_000;
|
|
7
|
+
const KEY_LENGTH_BYTES = 32;
|
|
8
|
+
const GCM_IV_LENGTH_BYTES = 12;
|
|
9
|
+
const PBKDF2_SALT_LENGTH_BYTES = 16;
|
|
10
|
+
let cachedMachineId;
|
|
11
|
+
export function getMachineId() {
|
|
12
|
+
if (cachedMachineId) {
|
|
13
|
+
return cachedMachineId;
|
|
14
|
+
}
|
|
15
|
+
const currentPlatform = platform();
|
|
16
|
+
if (currentPlatform === 'darwin') {
|
|
17
|
+
try {
|
|
18
|
+
const output = execSync('ioreg -rd1 -c IOPlatformExpertDevice', {
|
|
19
|
+
encoding: 'utf-8',
|
|
20
|
+
stdio: 'pipe',
|
|
21
|
+
});
|
|
22
|
+
const match = output.match(/"IOPlatformUUID"\s*=\s*"([^"]+)"/);
|
|
23
|
+
if (match?.[1]) {
|
|
24
|
+
cachedMachineId = match[1].trim();
|
|
25
|
+
return cachedMachineId;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
catch { }
|
|
29
|
+
}
|
|
30
|
+
if (currentPlatform === 'linux') {
|
|
31
|
+
try {
|
|
32
|
+
const machineId = readFileSync('/etc/machine-id', 'utf-8').trim();
|
|
33
|
+
if (machineId) {
|
|
34
|
+
cachedMachineId = machineId;
|
|
35
|
+
return cachedMachineId;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch { }
|
|
39
|
+
}
|
|
40
|
+
if (currentPlatform === 'win32') {
|
|
41
|
+
try {
|
|
42
|
+
const output = execSync('reg query "HKLM\\SOFTWARE\\Microsoft\\Cryptography" /v MachineGuid', {
|
|
43
|
+
encoding: 'utf-8',
|
|
44
|
+
stdio: 'pipe',
|
|
45
|
+
});
|
|
46
|
+
const match = output.match(/MachineGuid\s+REG_\w+\s+([^\r\n]+)/i);
|
|
47
|
+
if (match?.[1]) {
|
|
48
|
+
cachedMachineId = match[1].trim();
|
|
49
|
+
return cachedMachineId;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch { }
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
cachedMachineId = `${hostname()}${userInfo().username}`;
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
cachedMachineId = hostname();
|
|
59
|
+
}
|
|
60
|
+
return cachedMachineId;
|
|
61
|
+
}
|
|
62
|
+
export async function encrypt(plaintext) {
|
|
63
|
+
const machineId = getMachineId();
|
|
64
|
+
const salt = randomBytes(PBKDF2_SALT_LENGTH_BYTES);
|
|
65
|
+
const iv = randomBytes(GCM_IV_LENGTH_BYTES);
|
|
66
|
+
const key = pbkdf2Sync(`${machineId}${KITT_SALT}`, salt, PBKDF2_ITERATIONS, KEY_LENGTH_BYTES, 'sha256');
|
|
67
|
+
const cipher = createCipheriv('aes-256-gcm', key, iv);
|
|
68
|
+
const encrypted = Buffer.concat([
|
|
69
|
+
cipher.update(plaintext, 'utf8'),
|
|
70
|
+
cipher.final(),
|
|
71
|
+
]);
|
|
72
|
+
const authTag = cipher.getAuthTag();
|
|
73
|
+
return {
|
|
74
|
+
encrypted: encrypted.toString('base64'),
|
|
75
|
+
iv: iv.toString('base64'),
|
|
76
|
+
salt: salt.toString('base64'),
|
|
77
|
+
authTag: authTag.toString('base64'),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
export async function decrypt(data) {
|
|
81
|
+
try {
|
|
82
|
+
const machineId = getMachineId();
|
|
83
|
+
const salt = Buffer.from(data.salt, 'base64');
|
|
84
|
+
const iv = Buffer.from(data.iv, 'base64');
|
|
85
|
+
const encrypted = Buffer.from(data.encrypted, 'base64');
|
|
86
|
+
const authTag = Buffer.from(data.authTag, 'base64');
|
|
87
|
+
const key = pbkdf2Sync(`${machineId}${KITT_SALT}`, salt, PBKDF2_ITERATIONS, KEY_LENGTH_BYTES, 'sha256');
|
|
88
|
+
const decipher = createDecipheriv('aes-256-gcm', key, iv);
|
|
89
|
+
decipher.setAuthTag(authTag);
|
|
90
|
+
const decrypted = Buffer.concat([
|
|
91
|
+
decipher.update(encrypted),
|
|
92
|
+
decipher.final(),
|
|
93
|
+
]);
|
|
94
|
+
return decrypted.toString('utf8');
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
throw new Error('Failed to decrypt credential data. Data may be invalid, tampered, or from a different machine.');
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=encryption.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.js","sourceRoot":"","sources":["../../src/credentials/encryption.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface KeychainResult {
|
|
2
|
+
success: boolean;
|
|
3
|
+
error?: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function isKeychainAvailable(): Promise<boolean>;
|
|
6
|
+
export declare function setKeychainValue(key: string, value: string): Promise<KeychainResult>;
|
|
7
|
+
export declare function getKeychainValue(key: string): Promise<string | null>;
|
|
8
|
+
export declare function deleteKeychainValue(key: string): Promise<KeychainResult>;
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
const SERVICE_NAME = "openkitt";
|
|
3
|
+
function normalizeKey(key) {
|
|
4
|
+
return key.startsWith(`${SERVICE_NAME}-`) ? key : `${SERVICE_NAME}-${key}`;
|
|
5
|
+
}
|
|
6
|
+
function isNotFoundError(errorMessage) {
|
|
7
|
+
const normalized = errorMessage.toLowerCase();
|
|
8
|
+
return (normalized.includes("could not be found") ||
|
|
9
|
+
normalized.includes("item not found") ||
|
|
10
|
+
normalized.includes("not found") ||
|
|
11
|
+
normalized.includes("element not found"));
|
|
12
|
+
}
|
|
13
|
+
function getErrorMessage(error) {
|
|
14
|
+
if (error instanceof Error) {
|
|
15
|
+
const maybeStderr = error.stderr;
|
|
16
|
+
if (typeof maybeStderr === "string" && maybeStderr.trim().length > 0) {
|
|
17
|
+
return maybeStderr.trim();
|
|
18
|
+
}
|
|
19
|
+
if (Buffer.isBuffer(maybeStderr) && maybeStderr.length > 0) {
|
|
20
|
+
return maybeStderr.toString("utf-8").trim();
|
|
21
|
+
}
|
|
22
|
+
if (error.message.trim().length > 0) {
|
|
23
|
+
return error.message.trim();
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return "Unknown keychain error";
|
|
27
|
+
}
|
|
28
|
+
function runPowerShellEncoded(script) {
|
|
29
|
+
const encodedCommand = Buffer.from(script, "utf16le").toString("base64");
|
|
30
|
+
return execFileSync("powershell", ["-NoProfile", "-EncodedCommand", encodedCommand], {
|
|
31
|
+
encoding: "utf-8",
|
|
32
|
+
stdio: "pipe"
|
|
33
|
+
}).trim();
|
|
34
|
+
}
|
|
35
|
+
function getWindowsReadScript(targetName) {
|
|
36
|
+
const escapedTarget = targetName.replace(/'/g, "''");
|
|
37
|
+
return `$ErrorActionPreference = 'Stop'
|
|
38
|
+
|
|
39
|
+
Add-Type @"
|
|
40
|
+
using System;
|
|
41
|
+
using System.Runtime.InteropServices;
|
|
42
|
+
|
|
43
|
+
public static class WinCred {
|
|
44
|
+
[DllImport("Advapi32.dll", EntryPoint = "CredReadW", CharSet = CharSet.Unicode, SetLastError = true)]
|
|
45
|
+
public static extern bool CredRead(string target, int type, int reservedFlag, out IntPtr credentialPtr);
|
|
46
|
+
|
|
47
|
+
[DllImport("Advapi32.dll", EntryPoint = "CredFree", SetLastError = true)]
|
|
48
|
+
public static extern void CredFree(IntPtr cred);
|
|
49
|
+
|
|
50
|
+
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
|
51
|
+
public struct CREDENTIAL {
|
|
52
|
+
public int Flags;
|
|
53
|
+
public int Type;
|
|
54
|
+
public string TargetName;
|
|
55
|
+
public string Comment;
|
|
56
|
+
public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten;
|
|
57
|
+
public int CredentialBlobSize;
|
|
58
|
+
public IntPtr CredentialBlob;
|
|
59
|
+
public int Persist;
|
|
60
|
+
public int AttributeCount;
|
|
61
|
+
public IntPtr Attributes;
|
|
62
|
+
public string TargetAlias;
|
|
63
|
+
public string UserName;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
"@
|
|
67
|
+
|
|
68
|
+
$target = '${escapedTarget}'
|
|
69
|
+
$credPtr = [IntPtr]::Zero
|
|
70
|
+
|
|
71
|
+
if (-not [WinCred]::CredRead($target, 1, 0, [ref]$credPtr)) {
|
|
72
|
+
exit 2
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
$credential = [System.Runtime.InteropServices.Marshal]::PtrToStructure($credPtr, [type][WinCred+CREDENTIAL])
|
|
77
|
+
if ($credential.CredentialBlobSize -le 0 -or $credential.CredentialBlob -eq [IntPtr]::Zero) {
|
|
78
|
+
exit 3
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
$bytes = New-Object byte[] $credential.CredentialBlobSize
|
|
82
|
+
[System.Runtime.InteropServices.Marshal]::Copy($credential.CredentialBlob, $bytes, 0, $credential.CredentialBlobSize)
|
|
83
|
+
$secret = [System.Text.Encoding]::Unicode.GetString($bytes)
|
|
84
|
+
Write-Output $secret
|
|
85
|
+
} finally {
|
|
86
|
+
[WinCred]::CredFree($credPtr)
|
|
87
|
+
}`;
|
|
88
|
+
}
|
|
89
|
+
function checkMacAvailable() {
|
|
90
|
+
execFileSync("security", ["-h"], {
|
|
91
|
+
encoding: "utf-8",
|
|
92
|
+
stdio: "pipe"
|
|
93
|
+
});
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
function checkLinuxAvailable() {
|
|
97
|
+
execFileSync("secret-tool", ["--help"], {
|
|
98
|
+
encoding: "utf-8",
|
|
99
|
+
stdio: "pipe"
|
|
100
|
+
});
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
function checkWindowsAvailable() {
|
|
104
|
+
execFileSync("cmdkey", ["/?"], {
|
|
105
|
+
encoding: "utf-8",
|
|
106
|
+
stdio: "pipe"
|
|
107
|
+
});
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
export async function isKeychainAvailable() {
|
|
111
|
+
try {
|
|
112
|
+
switch (process.platform) {
|
|
113
|
+
case "darwin":
|
|
114
|
+
return checkMacAvailable();
|
|
115
|
+
case "linux":
|
|
116
|
+
return checkLinuxAvailable();
|
|
117
|
+
case "win32":
|
|
118
|
+
return checkWindowsAvailable();
|
|
119
|
+
default:
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
export async function setKeychainValue(key, value) {
|
|
128
|
+
const normalizedKey = normalizeKey(key);
|
|
129
|
+
try {
|
|
130
|
+
switch (process.platform) {
|
|
131
|
+
case "darwin":
|
|
132
|
+
execFileSync("security", [
|
|
133
|
+
"add-generic-password",
|
|
134
|
+
"-a",
|
|
135
|
+
normalizedKey,
|
|
136
|
+
"-s",
|
|
137
|
+
SERVICE_NAME,
|
|
138
|
+
"-w",
|
|
139
|
+
value,
|
|
140
|
+
"-U"
|
|
141
|
+
], {
|
|
142
|
+
encoding: "utf-8",
|
|
143
|
+
stdio: "pipe"
|
|
144
|
+
});
|
|
145
|
+
return { success: true };
|
|
146
|
+
case "linux":
|
|
147
|
+
execFileSync("secret-tool", ["store", `--label=${SERVICE_NAME}`, "service", SERVICE_NAME, "key", normalizedKey], {
|
|
148
|
+
encoding: "utf-8",
|
|
149
|
+
stdio: "pipe",
|
|
150
|
+
input: value
|
|
151
|
+
});
|
|
152
|
+
return { success: true };
|
|
153
|
+
case "win32":
|
|
154
|
+
execFileSync("cmdkey", [
|
|
155
|
+
`/generic:${normalizedKey}`,
|
|
156
|
+
`/user:${SERVICE_NAME}`,
|
|
157
|
+
`/pass:${value}`
|
|
158
|
+
], {
|
|
159
|
+
encoding: "utf-8",
|
|
160
|
+
stdio: "pipe"
|
|
161
|
+
});
|
|
162
|
+
return { success: true };
|
|
163
|
+
default:
|
|
164
|
+
return { success: false, error: "Unsupported platform" };
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
return { success: false, error: getErrorMessage(error) };
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
export async function getKeychainValue(key) {
|
|
172
|
+
const normalizedKey = normalizeKey(key);
|
|
173
|
+
try {
|
|
174
|
+
switch (process.platform) {
|
|
175
|
+
case "darwin":
|
|
176
|
+
return execFileSync("security", ["find-generic-password", "-a", normalizedKey, "-s", SERVICE_NAME, "-w"], {
|
|
177
|
+
encoding: "utf-8",
|
|
178
|
+
stdio: "pipe"
|
|
179
|
+
}).trim();
|
|
180
|
+
case "linux":
|
|
181
|
+
return execFileSync("secret-tool", ["lookup", "service", SERVICE_NAME, "key", normalizedKey], {
|
|
182
|
+
encoding: "utf-8",
|
|
183
|
+
stdio: "pipe"
|
|
184
|
+
}).trim();
|
|
185
|
+
case "win32": {
|
|
186
|
+
const script = getWindowsReadScript(normalizedKey);
|
|
187
|
+
const output = runPowerShellEncoded(script);
|
|
188
|
+
return output.length > 0 ? output : null;
|
|
189
|
+
}
|
|
190
|
+
default:
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
catch (error) {
|
|
195
|
+
const errorMessage = getErrorMessage(error);
|
|
196
|
+
if (isNotFoundError(errorMessage)) {
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
export async function deleteKeychainValue(key) {
|
|
203
|
+
const normalizedKey = normalizeKey(key);
|
|
204
|
+
try {
|
|
205
|
+
switch (process.platform) {
|
|
206
|
+
case "darwin":
|
|
207
|
+
execFileSync("security", ["delete-generic-password", "-a", normalizedKey, "-s", SERVICE_NAME], {
|
|
208
|
+
encoding: "utf-8",
|
|
209
|
+
stdio: "pipe"
|
|
210
|
+
});
|
|
211
|
+
return { success: true };
|
|
212
|
+
case "linux":
|
|
213
|
+
execFileSync("secret-tool", ["clear", "service", SERVICE_NAME, "key", normalizedKey], {
|
|
214
|
+
encoding: "utf-8",
|
|
215
|
+
stdio: "pipe"
|
|
216
|
+
});
|
|
217
|
+
return { success: true };
|
|
218
|
+
case "win32":
|
|
219
|
+
execFileSync("cmdkey", [`/delete:${normalizedKey}`], {
|
|
220
|
+
encoding: "utf-8",
|
|
221
|
+
stdio: "pipe"
|
|
222
|
+
});
|
|
223
|
+
return { success: true };
|
|
224
|
+
default:
|
|
225
|
+
return { success: false, error: "Unsupported platform" };
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
catch (error) {
|
|
229
|
+
const errorMessage = getErrorMessage(error);
|
|
230
|
+
if (isNotFoundError(errorMessage)) {
|
|
231
|
+
return { success: true };
|
|
232
|
+
}
|
|
233
|
+
return { success: false, error: errorMessage };
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=keychain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keychain.js","sourceRoot":"","sources":["../../src/credentials/keychain.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface RailwayAuthStatus {
|
|
2
|
+
authenticated: boolean;
|
|
3
|
+
username?: string;
|
|
4
|
+
error?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function isRailwayInstalled(): Promise<boolean>;
|
|
7
|
+
export declare function checkRailwayAuth(): Promise<RailwayAuthStatus>;
|
|
8
|
+
export declare function railwayLogin(): Promise<RailwayAuthStatus>;
|
|
9
|
+
export declare function railwayLogout(): Promise<boolean>;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { execSync } from 'node:child_process';
|
|
2
|
+
export async function isRailwayInstalled() {
|
|
3
|
+
try {
|
|
4
|
+
execSync('railway --version', {
|
|
5
|
+
encoding: 'utf-8',
|
|
6
|
+
stdio: 'pipe',
|
|
7
|
+
});
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export async function checkRailwayAuth() {
|
|
15
|
+
const installed = await isRailwayInstalled();
|
|
16
|
+
if (!installed) {
|
|
17
|
+
return {
|
|
18
|
+
authenticated: false,
|
|
19
|
+
error: 'Railway CLI not installed',
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
const output = execSync('railway whoami', {
|
|
24
|
+
encoding: 'utf-8',
|
|
25
|
+
stdio: 'pipe',
|
|
26
|
+
}).trim();
|
|
27
|
+
if (output && output.length > 0) {
|
|
28
|
+
return {
|
|
29
|
+
authenticated: true,
|
|
30
|
+
username: output,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
authenticated: false,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return {
|
|
39
|
+
authenticated: false,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export async function railwayLogin() {
|
|
44
|
+
try {
|
|
45
|
+
execSync('railway login', {
|
|
46
|
+
stdio: 'inherit',
|
|
47
|
+
});
|
|
48
|
+
return await checkRailwayAuth();
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return {
|
|
52
|
+
authenticated: false,
|
|
53
|
+
error: 'Failed to complete Railway login',
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
export async function railwayLogout() {
|
|
58
|
+
try {
|
|
59
|
+
execSync('railway logout', {
|
|
60
|
+
encoding: 'utf-8',
|
|
61
|
+
stdio: 'pipe',
|
|
62
|
+
});
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=railway.js.map
|