ctxinit 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (221) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +484 -0
  3. package/bin/ctx.js +3 -0
  4. package/dist/analysis/index.d.ts +2 -0
  5. package/dist/analysis/index.d.ts.map +1 -0
  6. package/dist/analysis/index.js +18 -0
  7. package/dist/analysis/index.js.map +1 -0
  8. package/dist/analysis/static-analysis.d.ts +79 -0
  9. package/dist/analysis/static-analysis.d.ts.map +1 -0
  10. package/dist/analysis/static-analysis.js +279 -0
  11. package/dist/analysis/static-analysis.js.map +1 -0
  12. package/dist/bootstrap/index.d.ts +8 -0
  13. package/dist/bootstrap/index.d.ts.map +1 -0
  14. package/dist/bootstrap/index.js +13 -0
  15. package/dist/bootstrap/index.js.map +1 -0
  16. package/dist/bootstrap/orchestrator.d.ts +48 -0
  17. package/dist/bootstrap/orchestrator.d.ts.map +1 -0
  18. package/dist/bootstrap/orchestrator.js +363 -0
  19. package/dist/bootstrap/orchestrator.js.map +1 -0
  20. package/dist/bootstrap/validator.d.ts +25 -0
  21. package/dist/bootstrap/validator.d.ts.map +1 -0
  22. package/dist/bootstrap/validator.js +412 -0
  23. package/dist/bootstrap/validator.js.map +1 -0
  24. package/dist/build/atomic.d.ts +74 -0
  25. package/dist/build/atomic.d.ts.map +1 -0
  26. package/dist/build/atomic.js +235 -0
  27. package/dist/build/atomic.js.map +1 -0
  28. package/dist/build/index.d.ts +10 -0
  29. package/dist/build/index.d.ts.map +1 -0
  30. package/dist/build/index.js +26 -0
  31. package/dist/build/index.js.map +1 -0
  32. package/dist/build/lock.d.ts +102 -0
  33. package/dist/build/lock.d.ts.map +1 -0
  34. package/dist/build/lock.js +297 -0
  35. package/dist/build/lock.js.map +1 -0
  36. package/dist/build/manifest.d.ts +138 -0
  37. package/dist/build/manifest.d.ts.map +1 -0
  38. package/dist/build/manifest.js +269 -0
  39. package/dist/build/manifest.js.map +1 -0
  40. package/dist/build/orchestrator.d.ts +103 -0
  41. package/dist/build/orchestrator.d.ts.map +1 -0
  42. package/dist/build/orchestrator.js +524 -0
  43. package/dist/build/orchestrator.js.map +1 -0
  44. package/dist/cli/bootstrap.d.ts +77 -0
  45. package/dist/cli/bootstrap.d.ts.map +1 -0
  46. package/dist/cli/bootstrap.js +527 -0
  47. package/dist/cli/bootstrap.js.map +1 -0
  48. package/dist/cli/build.d.ts +32 -0
  49. package/dist/cli/build.d.ts.map +1 -0
  50. package/dist/cli/build.js +156 -0
  51. package/dist/cli/build.js.map +1 -0
  52. package/dist/cli/diff.d.ts +23 -0
  53. package/dist/cli/diff.d.ts.map +1 -0
  54. package/dist/cli/diff.js +226 -0
  55. package/dist/cli/diff.js.map +1 -0
  56. package/dist/cli/hooks.d.ts +29 -0
  57. package/dist/cli/hooks.d.ts.map +1 -0
  58. package/dist/cli/hooks.js +176 -0
  59. package/dist/cli/hooks.js.map +1 -0
  60. package/dist/cli/init.d.ts +53 -0
  61. package/dist/cli/init.d.ts.map +1 -0
  62. package/dist/cli/init.js +254 -0
  63. package/dist/cli/init.js.map +1 -0
  64. package/dist/cli/lint.d.ts +46 -0
  65. package/dist/cli/lint.d.ts.map +1 -0
  66. package/dist/cli/lint.js +210 -0
  67. package/dist/cli/lint.js.map +1 -0
  68. package/dist/cli/migrate.d.ts +28 -0
  69. package/dist/cli/migrate.d.ts.map +1 -0
  70. package/dist/cli/migrate.js +350 -0
  71. package/dist/cli/migrate.js.map +1 -0
  72. package/dist/cli/verify.d.ts +21 -0
  73. package/dist/cli/verify.d.ts.map +1 -0
  74. package/dist/cli/verify.js +209 -0
  75. package/dist/cli/verify.js.map +1 -0
  76. package/dist/cli.d.ts +8 -0
  77. package/dist/cli.d.ts.map +1 -0
  78. package/dist/cli.js +262 -0
  79. package/dist/cli.js.map +1 -0
  80. package/dist/compiler/agents-compiler.d.ts +24 -0
  81. package/dist/compiler/agents-compiler.d.ts.map +1 -0
  82. package/dist/compiler/agents-compiler.js +192 -0
  83. package/dist/compiler/agents-compiler.js.map +1 -0
  84. package/dist/compiler/base-compiler.d.ts +152 -0
  85. package/dist/compiler/base-compiler.d.ts.map +1 -0
  86. package/dist/compiler/base-compiler.js +180 -0
  87. package/dist/compiler/base-compiler.js.map +1 -0
  88. package/dist/compiler/claude-compiler.d.ts +24 -0
  89. package/dist/compiler/claude-compiler.d.ts.map +1 -0
  90. package/dist/compiler/claude-compiler.js +182 -0
  91. package/dist/compiler/claude-compiler.js.map +1 -0
  92. package/dist/compiler/cursor-compiler.d.ts +33 -0
  93. package/dist/compiler/cursor-compiler.d.ts.map +1 -0
  94. package/dist/compiler/cursor-compiler.js +136 -0
  95. package/dist/compiler/cursor-compiler.js.map +1 -0
  96. package/dist/compiler/index.d.ts +7 -0
  97. package/dist/compiler/index.d.ts.map +1 -0
  98. package/dist/compiler/index.js +24 -0
  99. package/dist/compiler/index.js.map +1 -0
  100. package/dist/compiler/rule-selector.d.ts +115 -0
  101. package/dist/compiler/rule-selector.d.ts.map +1 -0
  102. package/dist/compiler/rule-selector.js +273 -0
  103. package/dist/compiler/rule-selector.js.map +1 -0
  104. package/dist/compiler/token-estimator.d.ts +74 -0
  105. package/dist/compiler/token-estimator.d.ts.map +1 -0
  106. package/dist/compiler/token-estimator.js +191 -0
  107. package/dist/compiler/token-estimator.js.map +1 -0
  108. package/dist/config/index.d.ts +2 -0
  109. package/dist/config/index.d.ts.map +1 -0
  110. package/dist/config/index.js +18 -0
  111. package/dist/config/index.js.map +1 -0
  112. package/dist/config/loader.d.ts +48 -0
  113. package/dist/config/loader.d.ts.map +1 -0
  114. package/dist/config/loader.js +175 -0
  115. package/dist/config/loader.js.map +1 -0
  116. package/dist/git/gitignore.d.ts +59 -0
  117. package/dist/git/gitignore.d.ts.map +1 -0
  118. package/dist/git/gitignore.js +268 -0
  119. package/dist/git/gitignore.js.map +1 -0
  120. package/dist/git/hooks.d.ts +34 -0
  121. package/dist/git/hooks.d.ts.map +1 -0
  122. package/dist/git/hooks.js +129 -0
  123. package/dist/git/hooks.js.map +1 -0
  124. package/dist/git/husky.d.ts +52 -0
  125. package/dist/git/husky.d.ts.map +1 -0
  126. package/dist/git/husky.js +219 -0
  127. package/dist/git/husky.js.map +1 -0
  128. package/dist/git/index.d.ts +9 -0
  129. package/dist/git/index.d.ts.map +1 -0
  130. package/dist/git/index.js +15 -0
  131. package/dist/git/index.js.map +1 -0
  132. package/dist/index.d.ts +6 -0
  133. package/dist/index.d.ts.map +1 -0
  134. package/dist/index.js +23 -0
  135. package/dist/index.js.map +1 -0
  136. package/dist/llm/base-provider.d.ts +43 -0
  137. package/dist/llm/base-provider.d.ts.map +1 -0
  138. package/dist/llm/base-provider.js +91 -0
  139. package/dist/llm/base-provider.js.map +1 -0
  140. package/dist/llm/index.d.ts +17 -0
  141. package/dist/llm/index.d.ts.map +1 -0
  142. package/dist/llm/index.js +36 -0
  143. package/dist/llm/index.js.map +1 -0
  144. package/dist/llm/prompts/bootstrap-prompt.d.ts +27 -0
  145. package/dist/llm/prompts/bootstrap-prompt.d.ts.map +1 -0
  146. package/dist/llm/prompts/bootstrap-prompt.js +278 -0
  147. package/dist/llm/prompts/bootstrap-prompt.js.map +1 -0
  148. package/dist/llm/prompts/index.d.ts +5 -0
  149. package/dist/llm/prompts/index.d.ts.map +1 -0
  150. package/dist/llm/prompts/index.js +11 -0
  151. package/dist/llm/prompts/index.js.map +1 -0
  152. package/dist/llm/provider-factory.d.ts +27 -0
  153. package/dist/llm/provider-factory.d.ts.map +1 -0
  154. package/dist/llm/provider-factory.js +213 -0
  155. package/dist/llm/provider-factory.js.map +1 -0
  156. package/dist/llm/providers/claude-api.d.ts +21 -0
  157. package/dist/llm/providers/claude-api.d.ts.map +1 -0
  158. package/dist/llm/providers/claude-api.js +110 -0
  159. package/dist/llm/providers/claude-api.js.map +1 -0
  160. package/dist/llm/providers/claude-code.d.ts +21 -0
  161. package/dist/llm/providers/claude-code.d.ts.map +1 -0
  162. package/dist/llm/providers/claude-code.js +120 -0
  163. package/dist/llm/providers/claude-code.js.map +1 -0
  164. package/dist/llm/providers/codex-cli.d.ts +25 -0
  165. package/dist/llm/providers/codex-cli.d.ts.map +1 -0
  166. package/dist/llm/providers/codex-cli.js +129 -0
  167. package/dist/llm/providers/codex-cli.js.map +1 -0
  168. package/dist/llm/providers/cursor-cli.d.ts +24 -0
  169. package/dist/llm/providers/cursor-cli.d.ts.map +1 -0
  170. package/dist/llm/providers/cursor-cli.js +106 -0
  171. package/dist/llm/providers/cursor-cli.js.map +1 -0
  172. package/dist/llm/providers/gemini-api.d.ts +20 -0
  173. package/dist/llm/providers/gemini-api.d.ts.map +1 -0
  174. package/dist/llm/providers/gemini-api.js +121 -0
  175. package/dist/llm/providers/gemini-api.js.map +1 -0
  176. package/dist/llm/providers/gemini-cli.d.ts +20 -0
  177. package/dist/llm/providers/gemini-cli.d.ts.map +1 -0
  178. package/dist/llm/providers/gemini-cli.js +109 -0
  179. package/dist/llm/providers/gemini-cli.js.map +1 -0
  180. package/dist/llm/providers/interactive.d.ts +42 -0
  181. package/dist/llm/providers/interactive.d.ts.map +1 -0
  182. package/dist/llm/providers/interactive.js +200 -0
  183. package/dist/llm/providers/interactive.js.map +1 -0
  184. package/dist/llm/providers/openai-api.d.ts +21 -0
  185. package/dist/llm/providers/openai-api.d.ts.map +1 -0
  186. package/dist/llm/providers/openai-api.js +107 -0
  187. package/dist/llm/providers/openai-api.js.map +1 -0
  188. package/dist/llm/types.d.ts +128 -0
  189. package/dist/llm/types.d.ts.map +1 -0
  190. package/dist/llm/types.js +8 -0
  191. package/dist/llm/types.js.map +1 -0
  192. package/dist/parser/index.d.ts +3 -0
  193. package/dist/parser/index.d.ts.map +1 -0
  194. package/dist/parser/index.js +19 -0
  195. package/dist/parser/index.js.map +1 -0
  196. package/dist/parser/path-security.d.ts +40 -0
  197. package/dist/parser/path-security.d.ts.map +1 -0
  198. package/dist/parser/path-security.js +183 -0
  199. package/dist/parser/path-security.js.map +1 -0
  200. package/dist/parser/rule-parser.d.ts +50 -0
  201. package/dist/parser/rule-parser.d.ts.map +1 -0
  202. package/dist/parser/rule-parser.js +203 -0
  203. package/dist/parser/rule-parser.js.map +1 -0
  204. package/dist/schemas/config.d.ts +202 -0
  205. package/dist/schemas/config.d.ts.map +1 -0
  206. package/dist/schemas/config.js +96 -0
  207. package/dist/schemas/config.js.map +1 -0
  208. package/dist/schemas/index.d.ts +3 -0
  209. package/dist/schemas/index.d.ts.map +1 -0
  210. package/dist/schemas/index.js +19 -0
  211. package/dist/schemas/index.js.map +1 -0
  212. package/dist/schemas/rule.d.ts +67 -0
  213. package/dist/schemas/rule.d.ts.map +1 -0
  214. package/dist/schemas/rule.js +44 -0
  215. package/dist/schemas/rule.js.map +1 -0
  216. package/package.json +69 -0
  217. package/templates/architecture.md +35 -0
  218. package/templates/bootstrap-prompt.md +242 -0
  219. package/templates/config.yaml +25 -0
  220. package/templates/project.md +44 -0
  221. package/templates/rules/example.md +36 -0
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ /**
3
+ * Google Gemini API Provider
4
+ *
5
+ * Uses Google's Gemini API for LLM invocation.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.GeminiAPIProvider = void 0;
9
+ const base_provider_1 = require("../base-provider");
10
+ /**
11
+ * Gemini API provider implementation
12
+ */
13
+ class GeminiAPIProvider extends base_provider_1.BaseLLMProvider {
14
+ static DEFAULT_MODEL = 'gemini-1.5-pro';
15
+ constructor(config) {
16
+ super(config);
17
+ }
18
+ get type() {
19
+ return 'gemini-api';
20
+ }
21
+ get name() {
22
+ return 'Google Gemini API';
23
+ }
24
+ get capabilities() {
25
+ return {
26
+ jsonMode: true,
27
+ systemPrompt: true,
28
+ streaming: true,
29
+ maxContextTokens: 1000000, // Gemini 1.5 Pro has 1M context
30
+ maxOutputTokens: 8192,
31
+ };
32
+ }
33
+ async isAvailable() {
34
+ const apiKey = this.config.apiKey || process.env.GOOGLE_API_KEY || process.env.GEMINI_API_KEY;
35
+ return !!apiKey;
36
+ }
37
+ async complete(request) {
38
+ const apiKey = this.config.apiKey || process.env.GOOGLE_API_KEY || process.env.GEMINI_API_KEY;
39
+ if (!apiKey) {
40
+ throw new Error('GOOGLE_API_KEY or GEMINI_API_KEY not set');
41
+ }
42
+ const model = this.config.model || GeminiAPIProvider.DEFAULT_MODEL;
43
+ const maxTokens = this.getMaxTokens(request);
44
+ const temperature = this.getTemperature(request);
45
+ const apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${apiKey}`;
46
+ // Build contents array
47
+ const contents = [];
48
+ // Build system instruction
49
+ let systemInstruction = request.systemPrompt || '';
50
+ const systemMessages = request.messages.filter(m => m.role === 'system');
51
+ if (systemMessages.length > 0) {
52
+ systemInstruction = [systemInstruction, ...systemMessages.map(m => m.content)]
53
+ .filter(Boolean)
54
+ .join('\n\n');
55
+ }
56
+ // Add JSON instruction if requested
57
+ if (request.jsonMode) {
58
+ systemInstruction += '\n\nIMPORTANT: Respond with valid JSON only. No markdown, no explanation, just the JSON object.';
59
+ }
60
+ // Add user/assistant messages
61
+ for (const msg of request.messages) {
62
+ if (msg.role !== 'system') {
63
+ contents.push({
64
+ role: msg.role === 'assistant' ? 'model' : 'user',
65
+ parts: [{ text: msg.content }],
66
+ });
67
+ }
68
+ }
69
+ const body = {
70
+ contents,
71
+ generationConfig: {
72
+ maxOutputTokens: maxTokens,
73
+ temperature,
74
+ },
75
+ };
76
+ // Add system instruction if present
77
+ if (systemInstruction) {
78
+ body.systemInstruction = {
79
+ parts: [{ text: systemInstruction }],
80
+ };
81
+ }
82
+ // Enable JSON mode if requested
83
+ if (request.jsonMode) {
84
+ body.generationConfig.responseMimeType = 'application/json';
85
+ }
86
+ const controller = new AbortController();
87
+ const timeoutId = setTimeout(() => controller.abort(), this.getTimeout());
88
+ try {
89
+ const response = await fetch(apiUrl, {
90
+ method: 'POST',
91
+ headers: {
92
+ 'Content-Type': 'application/json',
93
+ },
94
+ body: JSON.stringify(body),
95
+ signal: controller.signal,
96
+ });
97
+ if (!response.ok) {
98
+ const errorText = await response.text();
99
+ // Sanitize any API key that might appear in error messages
100
+ const sanitizedError = errorText.replace(/key=[^&\s]+/gi, 'key=[REDACTED]');
101
+ throw new Error(`Gemini API error (${response.status}): ${sanitizedError}`);
102
+ }
103
+ const data = await response.json();
104
+ const content = data.candidates[0]?.content?.parts
105
+ ?.map(p => p.text)
106
+ .join('') || '';
107
+ return {
108
+ content,
109
+ promptTokens: data.usageMetadata?.promptTokenCount,
110
+ completionTokens: data.usageMetadata?.candidatesTokenCount,
111
+ totalTokens: data.usageMetadata?.totalTokenCount,
112
+ metadata: { model },
113
+ };
114
+ }
115
+ finally {
116
+ clearTimeout(timeoutId);
117
+ }
118
+ }
119
+ }
120
+ exports.GeminiAPIProvider = GeminiAPIProvider;
121
+ //# sourceMappingURL=gemini-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini-api.js","sourceRoot":"","sources":["../../../src/llm/providers/gemini-api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Gemini CLI Provider
3
+ *
4
+ * Uses Google's Gemini CLI tool for LLM invocation.
5
+ */
6
+ import { LLMProviderType, LLMProviderConfig, LLMProviderCapabilities, LLMRequest, LLMResponse } from '../types';
7
+ import { BaseLLMProvider } from '../base-provider';
8
+ /**
9
+ * Gemini CLI provider implementation
10
+ */
11
+ export declare class GeminiCLIProvider extends BaseLLMProvider {
12
+ private cliCommand;
13
+ constructor(config: LLMProviderConfig);
14
+ get type(): LLMProviderType;
15
+ get name(): string;
16
+ get capabilities(): LLMProviderCapabilities;
17
+ isAvailable(): Promise<boolean>;
18
+ complete(request: LLMRequest): Promise<LLMResponse>;
19
+ }
20
+ //# sourceMappingURL=gemini-cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini-cli.d.ts","sourceRoot":"","sources":["../../../src/llm/providers/gemini-cli.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,uBAAuB,EACvB,UAAU,EACV,WAAW,EACZ,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,eAAe;IACpD,OAAO,CAAC,UAAU,CAAS;gBAEf,MAAM,EAAE,iBAAiB;IAKrC,IAAI,IAAI,IAAI,eAAe,CAE1B;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,YAAY,IAAI,uBAAuB,CAQ1C;IAEK,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAY/B,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;CA0E1D"}
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ /**
3
+ * Gemini CLI Provider
4
+ *
5
+ * Uses Google's Gemini CLI tool for LLM invocation.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.GeminiCLIProvider = void 0;
9
+ const child_process_1 = require("child_process");
10
+ const base_provider_1 = require("../base-provider");
11
+ /**
12
+ * Gemini CLI provider implementation
13
+ */
14
+ class GeminiCLIProvider extends base_provider_1.BaseLLMProvider {
15
+ cliCommand;
16
+ constructor(config) {
17
+ super(config);
18
+ this.cliCommand = config.cliPath || 'gemini';
19
+ }
20
+ get type() {
21
+ return 'gemini-cli';
22
+ }
23
+ get name() {
24
+ return 'Gemini CLI';
25
+ }
26
+ get capabilities() {
27
+ return {
28
+ jsonMode: false,
29
+ systemPrompt: true,
30
+ streaming: false,
31
+ maxContextTokens: 1000000,
32
+ maxOutputTokens: 8192,
33
+ };
34
+ }
35
+ async isAvailable() {
36
+ try {
37
+ (0, child_process_1.execSync)(`${this.cliCommand} --version`, {
38
+ stdio: 'pipe',
39
+ timeout: 5000,
40
+ });
41
+ return true;
42
+ }
43
+ catch {
44
+ return false;
45
+ }
46
+ }
47
+ async complete(request) {
48
+ const prompt = this.buildPromptFromMessages(request);
49
+ // Add JSON instruction if requested
50
+ const finalPrompt = request.jsonMode
51
+ ? `${prompt}\n\nIMPORTANT: Respond with valid JSON only. No markdown code blocks, no explanation, just the raw JSON object.`
52
+ : prompt;
53
+ return new Promise((resolve, reject) => {
54
+ const args = [];
55
+ // Add model if specified (must come before -p flag)
56
+ if (this.config.model) {
57
+ args.push('-m', this.config.model);
58
+ }
59
+ // Add prompt using -p flag (correct Gemini CLI syntax)
60
+ args.push('-p', finalPrompt);
61
+ this.log('Executing command', { command: this.cliCommand, args: args.slice(0, -1), promptLength: finalPrompt.length });
62
+ const child = (0, child_process_1.spawn)(this.cliCommand, args, {
63
+ stdio: ['pipe', 'pipe', 'pipe'],
64
+ timeout: this.getTimeout(),
65
+ });
66
+ let stdout = '';
67
+ let stderr = '';
68
+ child.stdout?.on('data', (data) => {
69
+ stdout += data.toString();
70
+ });
71
+ child.stderr?.on('data', (data) => {
72
+ stderr += data.toString();
73
+ });
74
+ child.on('error', (error) => {
75
+ reject(new Error(`Gemini CLI error: ${error.message}`));
76
+ });
77
+ // Set timeout
78
+ const timeoutId = setTimeout(() => {
79
+ child.kill('SIGTERM');
80
+ reject(new Error('Gemini CLI timed out'));
81
+ }, this.getTimeout());
82
+ child.on('close', (code) => {
83
+ clearTimeout(timeoutId);
84
+ this.log('Process exited', { code, stdoutLength: stdout.length, stderrLength: stderr.length });
85
+ if (code !== 0) {
86
+ const errorDetails = stderr.trim() || 'No error output captured';
87
+ this.log('Command failed', { errorDetails });
88
+ const suggestion = stderr.includes('command not found') || stderr.includes('not recognized')
89
+ ? '\nMake sure gemini CLI is installed. See: https://github.com/google-gemini/gemini-cli'
90
+ : stderr.includes('auth') || stderr.includes('API key')
91
+ ? '\nAuthentication issue - check your GOOGLE_API_KEY environment variable'
92
+ : '\nTry running with --verbose for more details.';
93
+ reject(new Error(`Gemini CLI failed (exit code ${code}):\n${errorDetails}${suggestion}`));
94
+ return;
95
+ }
96
+ this.log('Command succeeded', { responseLength: stdout.trim().length });
97
+ resolve({
98
+ content: stdout.trim(),
99
+ metadata: {
100
+ provider: 'gemini-cli',
101
+ command: this.cliCommand,
102
+ },
103
+ });
104
+ });
105
+ });
106
+ }
107
+ }
108
+ exports.GeminiCLIProvider = GeminiCLIProvider;
109
+ //# sourceMappingURL=gemini-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini-cli.js","sourceRoot":"","sources":["../../../src/llm/providers/gemini-cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Interactive Provider
3
+ *
4
+ * Manual mode where the user copies the prompt and pastes the LLM response.
5
+ * Useful when no API keys are available or for testing.
6
+ */
7
+ import { LLMProviderType, LLMProviderConfig, LLMProviderCapabilities, LLMRequest, LLMResponse } from '../types';
8
+ import { BaseLLMProvider } from '../base-provider';
9
+ /**
10
+ * Interactive (manual) provider implementation
11
+ */
12
+ export declare class InteractiveProvider extends BaseLLMProvider {
13
+ constructor(config: LLMProviderConfig);
14
+ get type(): LLMProviderType;
15
+ get name(): string;
16
+ get capabilities(): LLMProviderCapabilities;
17
+ isAvailable(): Promise<boolean>;
18
+ complete(request: LLMRequest): Promise<LLMResponse>;
19
+ /**
20
+ * Read multiline input from stdin until empty line or EOF
21
+ */
22
+ private readMultilineInput;
23
+ }
24
+ /**
25
+ * Stdin Provider
26
+ *
27
+ * Reads response from stdin (for piped input).
28
+ * Usage: echo "response" | ctx bootstrap --provider interactive
29
+ */
30
+ export declare class StdinProvider extends BaseLLMProvider {
31
+ constructor(config: LLMProviderConfig);
32
+ get type(): LLMProviderType;
33
+ get name(): string;
34
+ get capabilities(): LLMProviderCapabilities;
35
+ isAvailable(): Promise<boolean>;
36
+ complete(request: LLMRequest): Promise<LLMResponse>;
37
+ /**
38
+ * Read all content from stdin
39
+ */
40
+ private readStdin;
41
+ }
42
+ //# sourceMappingURL=interactive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactive.d.ts","sourceRoot":"","sources":["../../../src/llm/providers/interactive.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,uBAAuB,EACvB,UAAU,EACV,WAAW,EACZ,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,eAAe;gBAC1C,MAAM,EAAE,iBAAiB;IAIrC,IAAI,IAAI,IAAI,eAAe,CAE1B;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,YAAY,IAAI,uBAAuB,CAQ1C;IAEK,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAK/B,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;IAgCzD;;OAEG;YACW,kBAAkB;CA+BjC;AAED;;;;;GAKG;AACH,qBAAa,aAAc,SAAQ,eAAe;gBACpC,MAAM,EAAE,iBAAiB;IAIrC,IAAI,IAAI,IAAI,eAAe,CAE1B;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,YAAY,IAAI,uBAAuB,CAQ1C;IAEK,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAK/B,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;IAmBzD;;OAEG;YACW,SAAS;CAsBxB"}
@@ -0,0 +1,200 @@
1
+ "use strict";
2
+ /**
3
+ * Interactive Provider
4
+ *
5
+ * Manual mode where the user copies the prompt and pastes the LLM response.
6
+ * Useful when no API keys are available or for testing.
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
21
+ }) : function(o, v) {
22
+ o["default"] = v;
23
+ });
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ var __importDefault = (this && this.__importDefault) || function (mod) {
42
+ return (mod && mod.__esModule) ? mod : { "default": mod };
43
+ };
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.StdinProvider = exports.InteractiveProvider = void 0;
46
+ const readline = __importStar(require("readline"));
47
+ const chalk_1 = __importDefault(require("chalk"));
48
+ const base_provider_1 = require("../base-provider");
49
+ /**
50
+ * Interactive (manual) provider implementation
51
+ */
52
+ class InteractiveProvider extends base_provider_1.BaseLLMProvider {
53
+ constructor(config) {
54
+ super(config);
55
+ }
56
+ get type() {
57
+ return 'interactive';
58
+ }
59
+ get name() {
60
+ return 'Interactive (Manual)';
61
+ }
62
+ get capabilities() {
63
+ return {
64
+ jsonMode: false, // User must format correctly
65
+ systemPrompt: true,
66
+ streaming: false,
67
+ maxContextTokens: Infinity, // No limit
68
+ maxOutputTokens: Infinity, // No limit
69
+ };
70
+ }
71
+ async isAvailable() {
72
+ // Interactive mode is always available if we have a TTY
73
+ return process.stdin.isTTY === true;
74
+ }
75
+ async complete(request) {
76
+ const prompt = this.buildPromptFromMessages(request);
77
+ // Add JSON instruction if requested
78
+ const finalPrompt = request.jsonMode
79
+ ? `${prompt}\n\nIMPORTANT: Respond with valid JSON only. No markdown code blocks, no explanation, just the raw JSON object.`
80
+ : prompt;
81
+ console.log(chalk_1.default.cyan('\n' + '='.repeat(80)));
82
+ console.log(chalk_1.default.cyan.bold('COPY THE FOLLOWING PROMPT TO YOUR LLM:'));
83
+ console.log(chalk_1.default.cyan('='.repeat(80) + '\n'));
84
+ console.log(finalPrompt);
85
+ console.log(chalk_1.default.cyan('\n' + '='.repeat(80)));
86
+ console.log(chalk_1.default.cyan.bold('END OF PROMPT'));
87
+ console.log(chalk_1.default.cyan('='.repeat(80) + '\n'));
88
+ console.log(chalk_1.default.yellow('Paste the LLM response below.'));
89
+ console.log(chalk_1.default.yellow('When done, press Enter twice (empty line) or Ctrl+D:\n'));
90
+ const response = await this.readMultilineInput();
91
+ return {
92
+ content: response.trim(),
93
+ metadata: {
94
+ provider: 'interactive',
95
+ manual: true,
96
+ },
97
+ };
98
+ }
99
+ /**
100
+ * Read multiline input from stdin until empty line or EOF
101
+ */
102
+ async readMultilineInput() {
103
+ return new Promise((resolve) => {
104
+ const rl = readline.createInterface({
105
+ input: process.stdin,
106
+ output: process.stdout,
107
+ terminal: true,
108
+ });
109
+ const lines = [];
110
+ let emptyLineCount = 0;
111
+ rl.on('line', (line) => {
112
+ if (line === '') {
113
+ emptyLineCount++;
114
+ if (emptyLineCount >= 2) {
115
+ // Two consecutive empty lines = done
116
+ rl.close();
117
+ return;
118
+ }
119
+ lines.push(line);
120
+ }
121
+ else {
122
+ emptyLineCount = 0;
123
+ lines.push(line);
124
+ }
125
+ });
126
+ rl.on('close', () => {
127
+ resolve(lines.join('\n'));
128
+ });
129
+ });
130
+ }
131
+ }
132
+ exports.InteractiveProvider = InteractiveProvider;
133
+ /**
134
+ * Stdin Provider
135
+ *
136
+ * Reads response from stdin (for piped input).
137
+ * Usage: echo "response" | ctx bootstrap --provider interactive
138
+ */
139
+ class StdinProvider extends base_provider_1.BaseLLMProvider {
140
+ constructor(config) {
141
+ super(config);
142
+ }
143
+ get type() {
144
+ return 'interactive'; // Same type, different mode
145
+ }
146
+ get name() {
147
+ return 'Stdin (Piped)';
148
+ }
149
+ get capabilities() {
150
+ return {
151
+ jsonMode: false,
152
+ systemPrompt: true,
153
+ streaming: false,
154
+ maxContextTokens: Infinity,
155
+ maxOutputTokens: Infinity,
156
+ };
157
+ }
158
+ async isAvailable() {
159
+ // Available when stdin is piped (not a TTY)
160
+ return process.stdin.isTTY !== true;
161
+ }
162
+ async complete(request) {
163
+ const prompt = this.buildPromptFromMessages(request);
164
+ // Output prompt to stderr so it doesn't interfere with piping
165
+ console.error(chalk_1.default.cyan('Prompt sent to stderr for reference.'));
166
+ console.error(chalk_1.default.gray(prompt.slice(0, 500) + '...'));
167
+ // Read response from stdin
168
+ const response = await this.readStdin();
169
+ return {
170
+ content: response.trim(),
171
+ metadata: {
172
+ provider: 'stdin',
173
+ piped: true,
174
+ },
175
+ };
176
+ }
177
+ /**
178
+ * Read all content from stdin
179
+ */
180
+ async readStdin() {
181
+ return new Promise((resolve, reject) => {
182
+ let data = '';
183
+ process.stdin.setEncoding('utf8');
184
+ process.stdin.on('readable', () => {
185
+ let chunk;
186
+ while ((chunk = process.stdin.read()) !== null) {
187
+ data += chunk;
188
+ }
189
+ });
190
+ process.stdin.on('end', () => {
191
+ resolve(data);
192
+ });
193
+ process.stdin.on('error', (err) => {
194
+ reject(err);
195
+ });
196
+ });
197
+ }
198
+ }
199
+ exports.StdinProvider = StdinProvider;
200
+ //# sourceMappingURL=interactive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactive.js","sourceRoot":"","sources":["../../../src/llm/providers/interactive.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * OpenAI API Provider
3
+ *
4
+ * Supports OpenAI GPT models and Codex via API.
5
+ */
6
+ import { LLMProviderType, LLMProviderConfig, LLMProviderCapabilities, LLMRequest, LLMResponse } from '../types';
7
+ import { BaseLLMProvider } from '../base-provider';
8
+ /**
9
+ * OpenAI API provider implementation
10
+ */
11
+ export declare class OpenAIAPIProvider extends BaseLLMProvider {
12
+ private static readonly API_URL;
13
+ private static readonly DEFAULT_MODEL;
14
+ constructor(config: LLMProviderConfig);
15
+ get type(): LLMProviderType;
16
+ get name(): string;
17
+ get capabilities(): LLMProviderCapabilities;
18
+ isAvailable(): Promise<boolean>;
19
+ complete(request: LLMRequest): Promise<LLMResponse>;
20
+ }
21
+ //# sourceMappingURL=openai-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-api.d.ts","sourceRoot":"","sources":["../../../src/llm/providers/openai-api.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,uBAAuB,EACvB,UAAU,EACV,WAAW,EACZ,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,eAAe;IACpD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAgD;IAC/E,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAY;gBAErC,MAAM,EAAE,iBAAiB;IAIrC,IAAI,IAAI,IAAI,eAAe,CAE1B;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,YAAY,IAAI,uBAAuB,CAQ1C;IAEK,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAK/B,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;CAqF1D"}
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ /**
3
+ * OpenAI API Provider
4
+ *
5
+ * Supports OpenAI GPT models and Codex via API.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.OpenAIAPIProvider = void 0;
9
+ const base_provider_1 = require("../base-provider");
10
+ /**
11
+ * OpenAI API provider implementation
12
+ */
13
+ class OpenAIAPIProvider extends base_provider_1.BaseLLMProvider {
14
+ static API_URL = 'https://api.openai.com/v1/chat/completions';
15
+ static DEFAULT_MODEL = 'gpt-4o';
16
+ constructor(config) {
17
+ super(config);
18
+ }
19
+ get type() {
20
+ return 'openai-api';
21
+ }
22
+ get name() {
23
+ return 'OpenAI API';
24
+ }
25
+ get capabilities() {
26
+ return {
27
+ jsonMode: true, // GPT-4 supports JSON mode
28
+ systemPrompt: true,
29
+ streaming: true,
30
+ maxContextTokens: 128000,
31
+ maxOutputTokens: 16384,
32
+ };
33
+ }
34
+ async isAvailable() {
35
+ const apiKey = this.config.apiKey || process.env.OPENAI_API_KEY;
36
+ return !!apiKey;
37
+ }
38
+ async complete(request) {
39
+ const apiKey = this.config.apiKey || process.env.OPENAI_API_KEY;
40
+ if (!apiKey) {
41
+ throw new Error('OPENAI_API_KEY not set');
42
+ }
43
+ const model = this.config.model || OpenAIAPIProvider.DEFAULT_MODEL;
44
+ const maxTokens = this.getMaxTokens(request);
45
+ const temperature = this.getTemperature(request);
46
+ // Build messages array
47
+ const messages = [];
48
+ // Add system prompt
49
+ let systemPrompt = request.systemPrompt || '';
50
+ const systemMessages = request.messages.filter(m => m.role === 'system');
51
+ if (systemMessages.length > 0) {
52
+ systemPrompt = [systemPrompt, ...systemMessages.map(m => m.content)]
53
+ .filter(Boolean)
54
+ .join('\n\n');
55
+ }
56
+ if (systemPrompt) {
57
+ messages.push({ role: 'system', content: systemPrompt });
58
+ }
59
+ // Add other messages
60
+ for (const msg of request.messages) {
61
+ if (msg.role !== 'system') {
62
+ messages.push({ role: msg.role, content: msg.content });
63
+ }
64
+ }
65
+ const body = {
66
+ model,
67
+ max_tokens: maxTokens,
68
+ temperature,
69
+ messages,
70
+ };
71
+ // Enable JSON mode if requested
72
+ if (request.jsonMode) {
73
+ body.response_format = { type: 'json_object' };
74
+ }
75
+ const controller = new AbortController();
76
+ const timeoutId = setTimeout(() => controller.abort(), this.getTimeout());
77
+ try {
78
+ const response = await fetch(OpenAIAPIProvider.API_URL, {
79
+ method: 'POST',
80
+ headers: {
81
+ 'Content-Type': 'application/json',
82
+ 'Authorization': `Bearer ${apiKey}`,
83
+ },
84
+ body: JSON.stringify(body),
85
+ signal: controller.signal,
86
+ });
87
+ if (!response.ok) {
88
+ const errorText = await response.text();
89
+ throw new Error(`OpenAI API error (${response.status}): ${errorText}`);
90
+ }
91
+ const data = await response.json();
92
+ const content = data.choices[0]?.message?.content || '';
93
+ return {
94
+ content,
95
+ promptTokens: data.usage?.prompt_tokens,
96
+ completionTokens: data.usage?.completion_tokens,
97
+ totalTokens: data.usage?.total_tokens,
98
+ metadata: { model },
99
+ };
100
+ }
101
+ finally {
102
+ clearTimeout(timeoutId);
103
+ }
104
+ }
105
+ }
106
+ exports.OpenAIAPIProvider = OpenAIAPIProvider;
107
+ //# sourceMappingURL=openai-api.js.map