@ekkos/cli 0.2.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 (135) hide show
  1. package/dist/cache/LocalSessionStore.d.ts +129 -0
  2. package/dist/cache/LocalSessionStore.js +688 -0
  3. package/dist/cache/capture.d.ts +26 -0
  4. package/dist/cache/capture.js +461 -0
  5. package/dist/cache/index.d.ts +7 -0
  6. package/dist/cache/index.js +23 -0
  7. package/dist/cache/types.d.ts +147 -0
  8. package/dist/cache/types.js +40 -0
  9. package/dist/commands/init.d.ts +9 -0
  10. package/dist/commands/init.js +478 -0
  11. package/dist/commands/run.d.ts +12 -0
  12. package/dist/commands/run.js +829 -0
  13. package/dist/commands/setup.d.ts +6 -0
  14. package/dist/commands/setup.js +658 -0
  15. package/dist/commands/status.d.ts +1 -0
  16. package/dist/commands/status.js +109 -0
  17. package/dist/commands/test.d.ts +1 -0
  18. package/dist/commands/test.js +157 -0
  19. package/dist/deploy/agents.d.ts +15 -0
  20. package/dist/deploy/agents.js +72 -0
  21. package/dist/deploy/hooks.d.ts +16 -0
  22. package/dist/deploy/hooks.js +121 -0
  23. package/dist/deploy/index.d.ts +7 -0
  24. package/dist/deploy/index.js +24 -0
  25. package/dist/deploy/instructions.d.ts +12 -0
  26. package/dist/deploy/instructions.js +36 -0
  27. package/dist/deploy/mcp.d.ts +19 -0
  28. package/dist/deploy/mcp.js +109 -0
  29. package/dist/deploy/plugins.d.ts +19 -0
  30. package/dist/deploy/plugins.js +62 -0
  31. package/dist/deploy/settings.d.ts +8 -0
  32. package/dist/deploy/settings.js +84 -0
  33. package/dist/deploy/skills.d.ts +19 -0
  34. package/dist/deploy/skills.js +60 -0
  35. package/dist/index.d.ts +2 -0
  36. package/dist/index.js +71 -0
  37. package/dist/restore/RestoreOrchestrator.d.ts +48 -0
  38. package/dist/restore/RestoreOrchestrator.js +481 -0
  39. package/dist/restore/index.d.ts +4 -0
  40. package/dist/restore/index.js +20 -0
  41. package/dist/utils/platform.d.ts +29 -0
  42. package/dist/utils/platform.js +65 -0
  43. package/dist/utils/session-words.json +119 -0
  44. package/dist/utils/state.d.ts +57 -0
  45. package/dist/utils/state.js +186 -0
  46. package/dist/utils/templates.d.ts +24 -0
  47. package/dist/utils/templates.js +118 -0
  48. package/package.json +48 -0
  49. package/templates/CLAUDE.md +287 -0
  50. package/templates/README.md +378 -0
  51. package/templates/agents/README.md +182 -0
  52. package/templates/agents/code-reviewer.md +166 -0
  53. package/templates/agents/debug-detective.md +169 -0
  54. package/templates/agents/ekkOS_Vercel.md +99 -0
  55. package/templates/agents/extension-manager.md +229 -0
  56. package/templates/agents/git-companion.md +185 -0
  57. package/templates/agents/github-test-agent.md +321 -0
  58. package/templates/agents/railway-manager.md +179 -0
  59. package/templates/claude-plugins/PHASE2_COMPLETION.md +346 -0
  60. package/templates/claude-plugins/PLUGIN_PROPOSALS.md +1776 -0
  61. package/templates/claude-plugins/README.md +587 -0
  62. package/templates/claude-plugins/agents/code-reviewer.json +14 -0
  63. package/templates/claude-plugins/agents/debug-detective.json +15 -0
  64. package/templates/claude-plugins/agents/git-companion.json +14 -0
  65. package/templates/claude-plugins/blog-manager/.claude-plugin/plugin.json +8 -0
  66. package/templates/claude-plugins/blog-manager/commands/blog.md +691 -0
  67. package/templates/claude-plugins/golden-loop-monitor/.claude-plugin/plugin.json +8 -0
  68. package/templates/claude-plugins/golden-loop-monitor/commands/loop-status.md +434 -0
  69. package/templates/claude-plugins/learning-tracker/.claude-plugin/plugin.json +8 -0
  70. package/templates/claude-plugins/learning-tracker/commands/my-patterns.md +282 -0
  71. package/templates/claude-plugins/memory-lens/.claude-plugin/plugin.json +8 -0
  72. package/templates/claude-plugins/memory-lens/commands/memory-search.md +181 -0
  73. package/templates/claude-plugins/pattern-coach/.claude-plugin/plugin.json +8 -0
  74. package/templates/claude-plugins/pattern-coach/commands/forge.md +365 -0
  75. package/templates/claude-plugins/project-schema-validator/.claude-plugin/plugin.json +8 -0
  76. package/templates/claude-plugins/project-schema-validator/commands/validate-schema.md +582 -0
  77. package/templates/claude-plugins-admin/AGENT_TEAM_PROPOSALS.md +819 -0
  78. package/templates/claude-plugins-admin/README.md +446 -0
  79. package/templates/claude-plugins-admin/autonomous-admin-agent/.claude-plugin/plugin.json +8 -0
  80. package/templates/claude-plugins-admin/autonomous-admin-agent/commands/agent.md +595 -0
  81. package/templates/claude-plugins-admin/backend-agent/.claude-plugin/plugin.json +8 -0
  82. package/templates/claude-plugins-admin/backend-agent/commands/backend.md +798 -0
  83. package/templates/claude-plugins-admin/deploy-guardian/.claude-plugin/plugin.json +8 -0
  84. package/templates/claude-plugins-admin/deploy-guardian/commands/deploy.md +554 -0
  85. package/templates/claude-plugins-admin/frontend-agent/.claude-plugin/plugin.json +8 -0
  86. package/templates/claude-plugins-admin/frontend-agent/commands/frontend.md +881 -0
  87. package/templates/claude-plugins-admin/mcp-server-manager/.claude-plugin/plugin.json +8 -0
  88. package/templates/claude-plugins-admin/mcp-server-manager/commands/mcp.md +85 -0
  89. package/templates/claude-plugins-admin/memory-system-monitor/.claude-plugin/plugin.json +8 -0
  90. package/templates/claude-plugins-admin/memory-system-monitor/commands/memory-health.md +569 -0
  91. package/templates/claude-plugins-admin/qa-agent/.claude-plugin/plugin.json +8 -0
  92. package/templates/claude-plugins-admin/qa-agent/commands/qa.md +863 -0
  93. package/templates/claude-plugins-admin/tech-lead-agent/.claude-plugin/plugin.json +8 -0
  94. package/templates/claude-plugins-admin/tech-lead-agent/commands/lead.md +732 -0
  95. package/templates/commands/continue.md +47 -0
  96. package/templates/cursor-hooks/after-agent-response.sh +117 -0
  97. package/templates/cursor-hooks/before-submit-prompt.sh +419 -0
  98. package/templates/cursor-hooks/hooks.json +20 -0
  99. package/templates/cursor-hooks/lib/contract.sh +320 -0
  100. package/templates/cursor-hooks/stop.sh +75 -0
  101. package/templates/cursor-rules/ekkos-memory.md +187 -0
  102. package/templates/hooks/assistant-response.sh +96 -0
  103. package/templates/hooks/hooks.json +28 -0
  104. package/templates/hooks/lib/contract.sh +320 -0
  105. package/templates/hooks/lib/state.sh +158 -0
  106. package/templates/hooks/session-start.ps1 +41 -0
  107. package/templates/hooks/session-start.sh +318 -0
  108. package/templates/hooks/stop.ps1 +16 -0
  109. package/templates/hooks/stop.sh +989 -0
  110. package/templates/hooks/user-prompt-submit.ps1 +174 -0
  111. package/templates/hooks/user-prompt-submit.sh +587 -0
  112. package/templates/hooks-node/lib/state.js +187 -0
  113. package/templates/hooks-node/stop.js +416 -0
  114. package/templates/hooks-node/user-prompt-submit.js +337 -0
  115. package/templates/plan-template.md +306 -0
  116. package/templates/rules/00-hooks-contract.mdc +89 -0
  117. package/templates/rules/30-ekkos-core.mdc +188 -0
  118. package/templates/rules/31-ekkos-messages.mdc +78 -0
  119. package/templates/skills/continue/SKILL.md +169 -0
  120. package/templates/skills/ekkOS_Deep_Recall/Skill.md +282 -0
  121. package/templates/skills/ekkOS_Learn/Skill.md +265 -0
  122. package/templates/skills/ekkOS_Memory_First/Skill.md +206 -0
  123. package/templates/skills/ekkOS_Plan_Assist/Skill.md +302 -0
  124. package/templates/skills/ekkOS_Preferences/Skill.md +247 -0
  125. package/templates/skills/ekkOS_Reflect/Skill.md +257 -0
  126. package/templates/skills/ekkOS_Safety/Skill.md +265 -0
  127. package/templates/skills/ekkOS_Schema/Skill.md +251 -0
  128. package/templates/skills/ekkOS_Summary/Skill.md +257 -0
  129. package/templates/skills/ekkOS_Vault/Skill.md +287 -0
  130. package/templates/skills/permissions/Skill.md +322 -0
  131. package/templates/spec-template.md +159 -0
  132. package/templates/windsurf-hooks/before-submit-prompt.sh +238 -0
  133. package/templates/windsurf-hooks/hooks.json +10 -0
  134. package/templates/windsurf-hooks/lib/contract.sh +320 -0
  135. package/templates/windsurf-rules/ekkos-memory.md +129 -0
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ /**
3
+ * ekkOS Fast /continue - Local Cache Types
4
+ *
5
+ * Defines the data structures for the 3-tier restore chain:
6
+ * Tier 0: Local JSONL cache (~20ms)
7
+ * Tier 1: Redis hot cache (~150ms)
8
+ * Tier 2: Supabase cold store (~500ms)
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.INVALID_RESPONSE_PATTERNS = void 0;
12
+ exports.isValidAssistantResponse = isValidAssistantResponse;
13
+ /**
14
+ * Known placeholder strings that indicate incomplete/invalid responses
15
+ * These should NOT be treated as valid assistant_response content
16
+ */
17
+ exports.INVALID_RESPONSE_PATTERNS = [
18
+ '[object Object]',
19
+ 'null',
20
+ 'undefined',
21
+ '...',
22
+ 'Loading...',
23
+ 'Thinking...',
24
+ ];
25
+ /**
26
+ * Check if an assistant_response is valid (complete, not a placeholder)
27
+ */
28
+ function isValidAssistantResponse(response) {
29
+ if (!response)
30
+ return false;
31
+ const trimmed = response.trim();
32
+ if (trimmed.length === 0)
33
+ return false;
34
+ if (exports.INVALID_RESPONSE_PATTERNS.includes(trimmed))
35
+ return false;
36
+ // Also reject very short responses that look like placeholders
37
+ if (trimmed.length < 5 && !/\w{3,}/.test(trimmed))
38
+ return false;
39
+ return true;
40
+ }
@@ -0,0 +1,9 @@
1
+ interface InitOptions {
2
+ ide?: string;
3
+ key?: string;
4
+ force?: boolean;
5
+ skipHooks?: boolean;
6
+ skipSkills?: boolean;
7
+ }
8
+ export declare function init(options: InitOptions): Promise<void>;
9
+ export {};
@@ -0,0 +1,478 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.init = init;
7
+ const fs_1 = require("fs");
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const inquirer_1 = __importDefault(require("inquirer"));
10
+ const ora_1 = __importDefault(require("ora"));
11
+ const open_1 = __importDefault(require("open"));
12
+ const platform_1 = require("../utils/platform");
13
+ const mcp_1 = require("../deploy/mcp");
14
+ const settings_1 = require("../deploy/settings");
15
+ const hooks_1 = require("../deploy/hooks");
16
+ const skills_1 = require("../deploy/skills");
17
+ const agents_1 = require("../deploy/agents");
18
+ const plugins_1 = require("../deploy/plugins");
19
+ const instructions_1 = require("../deploy/instructions");
20
+ const templates_1 = require("../utils/templates");
21
+ // ═══════════════════════════════════════════════════════════════════════════
22
+ // DEVICE AUTHENTICATION
23
+ // ═══════════════════════════════════════════════════════════════════════════
24
+ async function requestDeviceCode() {
25
+ const response = await fetch(`${platform_1.PLATFORM_URL}/api/device-auth/codes`, {
26
+ method: 'POST',
27
+ headers: { 'Content-Type': 'application/json' }
28
+ });
29
+ if (!response.ok) {
30
+ throw new Error(`Failed to request device code: ${response.status}`);
31
+ }
32
+ return response.json();
33
+ }
34
+ async function pollForApproval(code, expiresIn) {
35
+ const pollInterval = 3000; // 3 seconds
36
+ const maxAttempts = Math.floor((expiresIn * 1000) / pollInterval);
37
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
38
+ const response = await fetch(`${platform_1.PLATFORM_URL}/api/device-auth/codes/${code}/status`, { method: 'GET' });
39
+ if (response.status === 410) {
40
+ return { status: 'expired' };
41
+ }
42
+ if (response.ok) {
43
+ const data = await response.json();
44
+ if (data.status !== 'pending') {
45
+ return data;
46
+ }
47
+ }
48
+ // Wait before next poll
49
+ await new Promise(resolve => setTimeout(resolve, pollInterval));
50
+ }
51
+ return { status: 'expired' };
52
+ }
53
+ async function generateApiKey(userId, email) {
54
+ const response = await fetch(`${platform_1.PLATFORM_URL}/api/auth/extension/generate`, {
55
+ method: 'POST',
56
+ headers: { 'Content-Type': 'application/json' },
57
+ body: JSON.stringify({ userId, email })
58
+ });
59
+ if (!response.ok) {
60
+ throw new Error(`Failed to generate API key: ${response.status}`);
61
+ }
62
+ return response.json();
63
+ }
64
+ async function deviceAuth() {
65
+ console.log('');
66
+ console.log(chalk_1.default.cyan('Step 1/3: Authentication'));
67
+ console.log(chalk_1.default.gray('─'.repeat(40)));
68
+ console.log('');
69
+ // Request device code
70
+ const spinner = (0, ora_1.default)('Requesting device code...').start();
71
+ let deviceCode;
72
+ try {
73
+ deviceCode = await requestDeviceCode();
74
+ spinner.succeed('Device code received');
75
+ }
76
+ catch (error) {
77
+ spinner.fail('Failed to get device code');
78
+ throw error;
79
+ }
80
+ console.log('');
81
+ console.log(chalk_1.default.white.bold(`Your code: ${chalk_1.default.cyan.bold(deviceCode.code)}`));
82
+ console.log('');
83
+ // Open browser
84
+ const verificationUrl = deviceCode.verificationUrl || `${platform_1.PLATFORM_URL}/activate`;
85
+ console.log(chalk_1.default.gray(`Opening browser to: ${verificationUrl}`));
86
+ try {
87
+ await (0, open_1.default)(verificationUrl);
88
+ }
89
+ catch {
90
+ console.log(chalk_1.default.yellow('Could not open browser automatically.'));
91
+ console.log(chalk_1.default.gray(`Please visit: ${verificationUrl}`));
92
+ }
93
+ console.log('');
94
+ // Poll for approval
95
+ const expiresMinutes = Math.floor(deviceCode.expiresIn / 60);
96
+ const pollSpinner = (0, ora_1.default)(`Waiting for approval... (expires in ${expiresMinutes} min)`).start();
97
+ let pollResult;
98
+ try {
99
+ pollResult = await pollForApproval(deviceCode.code, deviceCode.expiresIn);
100
+ }
101
+ catch (error) {
102
+ pollSpinner.fail('Authentication failed');
103
+ throw error;
104
+ }
105
+ if (pollResult.status === 'denied') {
106
+ pollSpinner.fail('Authentication denied');
107
+ throw new Error('User denied authentication request');
108
+ }
109
+ if (pollResult.status === 'expired') {
110
+ pollSpinner.fail('Authentication expired');
111
+ throw new Error('Device code expired. Please try again.');
112
+ }
113
+ if (pollResult.status !== 'approved' || !pollResult.user_id || !pollResult.user_email) {
114
+ pollSpinner.fail('Authentication failed');
115
+ throw new Error('Invalid approval response');
116
+ }
117
+ pollSpinner.succeed('Approved');
118
+ // Generate API key
119
+ const keySpinner = (0, ora_1.default)('Generating API key...').start();
120
+ let keyData;
121
+ try {
122
+ keyData = await generateApiKey(pollResult.user_id, pollResult.user_email);
123
+ keySpinner.succeed('API key generated');
124
+ }
125
+ catch (error) {
126
+ keySpinner.fail('Failed to generate API key');
127
+ throw error;
128
+ }
129
+ console.log('');
130
+ console.log(chalk_1.default.green(`✓ Authenticated as ${chalk_1.default.bold(keyData.email)} (${keyData.tier} tier)`));
131
+ console.log('');
132
+ return {
133
+ apiKey: keyData.apiKey,
134
+ userId: pollResult.user_id,
135
+ email: keyData.email,
136
+ tier: keyData.tier
137
+ };
138
+ }
139
+ // ═══════════════════════════════════════════════════════════════════════════
140
+ // MANUAL API KEY FLOW
141
+ // ═══════════════════════════════════════════════════════════════════════════
142
+ async function manualKeyAuth(providedKey) {
143
+ console.log('');
144
+ console.log(chalk_1.default.cyan('Step 1/3: Authentication'));
145
+ console.log(chalk_1.default.gray('─'.repeat(40)));
146
+ console.log('');
147
+ let apiKey = providedKey;
148
+ if (!apiKey) {
149
+ console.log(chalk_1.default.yellow('Get your API key from: https://platform.ekkos.dev/dashboard/keys'));
150
+ console.log('');
151
+ const answers = await inquirer_1.default.prompt([
152
+ {
153
+ type: 'password',
154
+ name: 'apiKey',
155
+ message: 'Enter your ekkOS API key:',
156
+ mask: '*',
157
+ validate: (input) => {
158
+ if (!input || input.length < 10) {
159
+ return 'Please enter a valid API key';
160
+ }
161
+ return true;
162
+ }
163
+ }
164
+ ]);
165
+ apiKey = answers.apiKey;
166
+ }
167
+ // Verify API key
168
+ const spinner = (0, ora_1.default)('Verifying API key...').start();
169
+ try {
170
+ const response = await fetch(`${platform_1.MCP_API_URL}/api/v1/patterns/query`, {
171
+ method: 'POST',
172
+ headers: {
173
+ 'Authorization': `Bearer ${apiKey}`,
174
+ 'Content-Type': 'application/json'
175
+ },
176
+ body: JSON.stringify({ query: 'test', k: 1 })
177
+ });
178
+ if (!response.ok) {
179
+ spinner.fail('Invalid API key');
180
+ throw new Error('API key verification failed');
181
+ }
182
+ spinner.succeed('API key verified');
183
+ }
184
+ catch (error) {
185
+ spinner.fail('Could not verify API key');
186
+ throw error;
187
+ }
188
+ console.log('');
189
+ console.log(chalk_1.default.green('✓ Authenticated with API key'));
190
+ console.log('');
191
+ // For manual keys, we don't have user info
192
+ return {
193
+ apiKey: apiKey,
194
+ userId: 'manual',
195
+ email: 'manual@ekkos.dev',
196
+ tier: 'unknown'
197
+ };
198
+ }
199
+ // ═══════════════════════════════════════════════════════════════════════════
200
+ // IDE SETUP
201
+ // ═══════════════════════════════════════════════════════════════════════════
202
+ async function selectIDEs() {
203
+ console.log(chalk_1.default.cyan('Step 2/3: IDE Setup'));
204
+ console.log(chalk_1.default.gray('─'.repeat(40)));
205
+ console.log('');
206
+ const detected = (0, platform_1.detectInstalledIDEs)();
207
+ const current = (0, platform_1.detectCurrentIDE)();
208
+ if (detected.length > 0) {
209
+ console.log(chalk_1.default.gray(`Detected: ${detected.join(', ')}`));
210
+ if (current) {
211
+ console.log(chalk_1.default.gray(`Current: ${current}`));
212
+ }
213
+ console.log('');
214
+ }
215
+ const ideOptions = [
216
+ { name: 'Claude Code', value: 'claude', default: detected.includes('claude') || current === 'claude' },
217
+ { name: 'Cursor', value: 'cursor', default: detected.includes('cursor') || current === 'cursor' },
218
+ { name: 'Windsurf (Cascade)', value: 'windsurf', default: detected.includes('windsurf') || current === 'windsurf' }
219
+ ];
220
+ const selectedIDEs = [];
221
+ // Ask for each IDE individually
222
+ for (const ide of ideOptions) {
223
+ const answer = await inquirer_1.default.prompt({
224
+ type: 'confirm',
225
+ name: 'selected',
226
+ message: `Configure ${ide.name}?`,
227
+ default: ide.default
228
+ });
229
+ if (answer.selected) {
230
+ selectedIDEs.push(ide.value);
231
+ }
232
+ }
233
+ if (selectedIDEs.length === 0) {
234
+ console.log(chalk_1.default.yellow('No IDEs selected. Defaulting to Claude Code.'));
235
+ selectedIDEs.push('claude');
236
+ }
237
+ console.log('');
238
+ return selectedIDEs;
239
+ }
240
+ async function deployForClaude(apiKey, userId, options) {
241
+ const result = {
242
+ mcp: false,
243
+ settings: false,
244
+ hooks: { count: 0, files: [] },
245
+ skills: { count: 0, skills: [] },
246
+ agents: { count: 0, agents: [] },
247
+ plugins: { count: 0, plugins: [] },
248
+ instructions: false
249
+ };
250
+ // MCP configuration
251
+ let spinner = (0, ora_1.default)('Deploying MCP server configuration...').start();
252
+ try {
253
+ (0, mcp_1.deployClaudeMcp)(apiKey, userId);
254
+ result.mcp = true;
255
+ spinner.succeed('MCP server configuration');
256
+ }
257
+ catch (error) {
258
+ spinner.fail('MCP server configuration failed');
259
+ }
260
+ // Settings.json (hook registration)
261
+ spinner = (0, ora_1.default)('Deploying hooks configuration...').start();
262
+ try {
263
+ (0, settings_1.deployClaudeSettings)();
264
+ result.settings = true;
265
+ spinner.succeed('Hooks configuration');
266
+ }
267
+ catch (error) {
268
+ spinner.fail('Hooks configuration failed');
269
+ }
270
+ // Hook scripts
271
+ if (!options.skipHooks) {
272
+ spinner = (0, ora_1.default)('Deploying hook scripts...').start();
273
+ try {
274
+ result.hooks = (0, hooks_1.deployHooks)(apiKey);
275
+ spinner.succeed(`Hook scripts (${result.hooks.count} files)`);
276
+ }
277
+ catch (error) {
278
+ spinner.fail('Hook scripts failed');
279
+ }
280
+ }
281
+ // Skills
282
+ if (!options.skipSkills) {
283
+ spinner = (0, ora_1.default)('Deploying skills...').start();
284
+ try {
285
+ result.skills = (0, skills_1.deploySkills)();
286
+ spinner.succeed(`Skills (${result.skills.count} folders)`);
287
+ }
288
+ catch (error) {
289
+ spinner.fail('Skills deployment failed');
290
+ }
291
+ }
292
+ // Agents
293
+ spinner = (0, ora_1.default)('Deploying agents...').start();
294
+ try {
295
+ result.agents = (0, agents_1.deployAgents)();
296
+ spinner.succeed(`Agents (${result.agents.count} files)`);
297
+ }
298
+ catch (error) {
299
+ spinner.fail('Agents deployment failed');
300
+ }
301
+ // Plugins
302
+ spinner = (0, ora_1.default)('Deploying plugins...').start();
303
+ try {
304
+ result.plugins = (0, plugins_1.deployPlugins)();
305
+ spinner.succeed(`Plugins (${result.plugins.count} folders)`);
306
+ }
307
+ catch (error) {
308
+ spinner.fail('Plugins deployment failed');
309
+ }
310
+ // CLAUDE.md
311
+ spinner = (0, ora_1.default)('Deploying global instructions...').start();
312
+ try {
313
+ (0, instructions_1.deployInstructions)();
314
+ result.instructions = true;
315
+ spinner.succeed('Global instructions (CLAUDE.md)');
316
+ }
317
+ catch (error) {
318
+ spinner.fail('Global instructions failed');
319
+ }
320
+ return result;
321
+ }
322
+ async function deployForCursor(apiKey, userId) {
323
+ const spinner = (0, ora_1.default)('Deploying Cursor MCP configuration...').start();
324
+ try {
325
+ (0, mcp_1.deployCursorMcp)(apiKey, userId);
326
+ spinner.succeed('Cursor MCP configuration');
327
+ return true;
328
+ }
329
+ catch (error) {
330
+ spinner.fail('Cursor MCP configuration failed');
331
+ return false;
332
+ }
333
+ }
334
+ async function deployForWindsurf(apiKey, userId) {
335
+ const spinner = (0, ora_1.default)('Deploying Windsurf MCP configuration...').start();
336
+ try {
337
+ (0, mcp_1.deployWindsurfMcp)(apiKey, userId);
338
+ spinner.succeed('Windsurf MCP configuration');
339
+ return true;
340
+ }
341
+ catch (error) {
342
+ spinner.fail('Windsurf MCP configuration failed');
343
+ return false;
344
+ }
345
+ }
346
+ // ═══════════════════════════════════════════════════════════════════════════
347
+ // MAIN INIT COMMAND
348
+ // ═══════════════════════════════════════════════════════════════════════════
349
+ async function init(options) {
350
+ console.log('');
351
+ console.log(chalk_1.default.cyan.bold('╔═══════════════════════════════════════╗'));
352
+ console.log(chalk_1.default.cyan.bold('║ 🧠 ekkOS Memory System Setup ║'));
353
+ console.log(chalk_1.default.cyan.bold('╚═══════════════════════════════════════╝'));
354
+ console.log('');
355
+ // Check templates exist
356
+ if (!(0, templates_1.templatesExist)()) {
357
+ console.log(chalk_1.default.red('Error: Templates not found.'));
358
+ console.log(chalk_1.default.gray('Please ensure the ekkOS CLI is installed correctly.'));
359
+ process.exit(1);
360
+ }
361
+ // Check for existing config
362
+ let existingConfig = null;
363
+ if ((0, fs_1.existsSync)(platform_1.EKKOS_CONFIG)) {
364
+ try {
365
+ existingConfig = JSON.parse((0, fs_1.readFileSync)(platform_1.EKKOS_CONFIG, 'utf-8'));
366
+ }
367
+ catch { }
368
+ }
369
+ // STEP 1: Authentication
370
+ let auth;
371
+ if (options.key) {
372
+ // Manual API key provided
373
+ auth = await manualKeyAuth(options.key);
374
+ }
375
+ else if (existingConfig?.apiKey && !options.force) {
376
+ // Already authenticated
377
+ console.log(chalk_1.default.cyan('Step 1/3: Authentication'));
378
+ console.log(chalk_1.default.gray('─'.repeat(40)));
379
+ console.log('');
380
+ console.log(chalk_1.default.green(`✓ Already authenticated as ${chalk_1.default.bold(existingConfig.email || 'unknown')}`));
381
+ console.log(chalk_1.default.gray(' (use --force to re-authenticate)'));
382
+ console.log('');
383
+ auth = {
384
+ apiKey: existingConfig.apiKey,
385
+ userId: existingConfig.userId || 'unknown',
386
+ email: existingConfig.email || 'unknown',
387
+ tier: existingConfig.tier || 'unknown'
388
+ };
389
+ }
390
+ else {
391
+ // Device auth flow
392
+ try {
393
+ auth = await deviceAuth();
394
+ }
395
+ catch (error) {
396
+ console.log(chalk_1.default.red(`\nAuthentication failed: ${error}`));
397
+ console.log(chalk_1.default.gray('\nTry again or use --key to provide an API key manually.'));
398
+ process.exit(1);
399
+ }
400
+ }
401
+ // STEP 2: IDE Selection
402
+ let selectedIDEs;
403
+ if (options.ide) {
404
+ if (options.ide === 'all') {
405
+ selectedIDEs = (0, platform_1.detectInstalledIDEs)();
406
+ if (selectedIDEs.length === 0) {
407
+ selectedIDEs = ['claude']; // Default to Claude Code
408
+ }
409
+ }
410
+ else {
411
+ selectedIDEs = [options.ide];
412
+ }
413
+ console.log(chalk_1.default.cyan('Step 2/3: IDE Setup'));
414
+ console.log(chalk_1.default.gray('─'.repeat(40)));
415
+ console.log('');
416
+ console.log(chalk_1.default.gray(`Configuring: ${selectedIDEs.join(', ')}`));
417
+ console.log('');
418
+ }
419
+ else {
420
+ selectedIDEs = await selectIDEs();
421
+ }
422
+ // STEP 3: Deployment
423
+ console.log(chalk_1.default.cyan('Step 3/3: Deploying'));
424
+ console.log(chalk_1.default.gray('─'.repeat(40)));
425
+ console.log('');
426
+ const installedIDEs = [];
427
+ for (const ide of selectedIDEs) {
428
+ if (ide === 'claude') {
429
+ const result = await deployForClaude(auth.apiKey, auth.userId, options);
430
+ if (result.mcp || result.hooks.count > 0) {
431
+ installedIDEs.push('claude');
432
+ }
433
+ }
434
+ else if (ide === 'cursor') {
435
+ if (await deployForCursor(auth.apiKey, auth.userId)) {
436
+ installedIDEs.push('cursor');
437
+ }
438
+ }
439
+ else if (ide === 'windsurf') {
440
+ if (await deployForWindsurf(auth.apiKey, auth.userId)) {
441
+ installedIDEs.push('windsurf');
442
+ }
443
+ }
444
+ }
445
+ // Save config
446
+ if (!(0, fs_1.existsSync)(platform_1.EKKOS_DIR)) {
447
+ (0, fs_1.mkdirSync)(platform_1.EKKOS_DIR, { recursive: true });
448
+ }
449
+ const config = {
450
+ apiKey: auth.apiKey,
451
+ userId: auth.userId,
452
+ email: auth.email,
453
+ tier: auth.tier,
454
+ createdAt: new Date().toISOString(),
455
+ installedIDEs
456
+ };
457
+ (0, fs_1.writeFileSync)(platform_1.EKKOS_CONFIG, JSON.stringify(config, null, 2));
458
+ (0, fs_1.chmodSync)(platform_1.EKKOS_CONFIG, '600'); // Secure permissions
459
+ // Summary
460
+ console.log('');
461
+ console.log(chalk_1.default.gray('═'.repeat(40)));
462
+ console.log(chalk_1.default.green.bold('✓ Setup complete!'));
463
+ console.log(chalk_1.default.gray('═'.repeat(40)));
464
+ console.log('');
465
+ if (installedIDEs.includes('claude')) {
466
+ console.log(chalk_1.default.yellow('→ Restart Claude Code to activate ekkOS'));
467
+ }
468
+ if (installedIDEs.includes('cursor')) {
469
+ console.log(chalk_1.default.yellow('→ Restart Cursor to activate ekkOS'));
470
+ }
471
+ if (installedIDEs.includes('windsurf')) {
472
+ console.log(chalk_1.default.yellow('→ Restart Windsurf to activate ekkOS'));
473
+ }
474
+ console.log('');
475
+ console.log(chalk_1.default.gray(`Run ${chalk_1.default.white('ekkos status')} to verify installation`));
476
+ console.log(chalk_1.default.gray(`View dashboard: ${chalk_1.default.white('https://platform.ekkos.dev/dashboard')}`));
477
+ console.log('');
478
+ }
@@ -0,0 +1,12 @@
1
+ interface RunOptions {
2
+ session?: string;
3
+ verbose?: boolean;
4
+ bypass?: boolean;
5
+ slashOpenDelayMs?: number;
6
+ charDelayMs?: number;
7
+ postEnterDelayMs?: number;
8
+ clearWaitMs?: number;
9
+ debugLogPath?: string;
10
+ }
11
+ export declare function run(options: RunOptions): Promise<void>;
12
+ export {};