@ekkos/cli 1.3.1 → 1.3.5

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 (131) hide show
  1. package/dist/capture/jsonl-rewriter.d.ts +1 -1
  2. package/dist/capture/jsonl-rewriter.js +3 -3
  3. package/dist/capture/transcript-repair.d.ts +2 -2
  4. package/dist/capture/transcript-repair.js +2 -2
  5. package/dist/commands/claw.d.ts +13 -0
  6. package/dist/commands/claw.js +253 -0
  7. package/dist/commands/dashboard.js +742 -118
  8. package/dist/commands/doctor.d.ts +3 -3
  9. package/dist/commands/doctor.js +6 -79
  10. package/dist/commands/gemini.d.ts +19 -0
  11. package/dist/commands/gemini.js +193 -0
  12. package/dist/commands/init.d.ts +1 -0
  13. package/dist/commands/init.js +56 -41
  14. package/dist/commands/run.d.ts +0 -1
  15. package/dist/commands/run.js +288 -263
  16. package/dist/commands/scan.d.ts +21 -0
  17. package/dist/commands/scan.js +386 -0
  18. package/dist/commands/status.d.ts +4 -1
  19. package/dist/commands/status.js +165 -27
  20. package/dist/commands/swarm-dashboard.js +156 -28
  21. package/dist/commands/swarm.d.ts +1 -1
  22. package/dist/commands/swarm.js +1 -1
  23. package/dist/commands/test-claude.d.ts +2 -2
  24. package/dist/commands/test-claude.js +3 -3
  25. package/dist/deploy/index.d.ts +0 -2
  26. package/dist/deploy/index.js +0 -2
  27. package/dist/deploy/settings.d.ts +6 -5
  28. package/dist/deploy/settings.js +64 -16
  29. package/dist/deploy/skills.js +1 -2
  30. package/dist/index.js +86 -96
  31. package/dist/lib/usage-parser.d.ts +1 -1
  32. package/dist/lib/usage-parser.js +9 -6
  33. package/dist/local/index.d.ts +14 -0
  34. package/dist/local/index.js +28 -0
  35. package/dist/local/local-embeddings.d.ts +49 -0
  36. package/dist/local/local-embeddings.js +232 -0
  37. package/dist/local/offline-fallback.d.ts +44 -0
  38. package/dist/local/offline-fallback.js +159 -0
  39. package/dist/local/sqlite-store.d.ts +126 -0
  40. package/dist/local/sqlite-store.js +393 -0
  41. package/dist/local/sync-engine.d.ts +42 -0
  42. package/dist/local/sync-engine.js +223 -0
  43. package/dist/utils/platform.d.ts +5 -1
  44. package/dist/utils/platform.js +24 -4
  45. package/dist/utils/proxy-url.d.ts +21 -0
  46. package/dist/utils/proxy-url.js +34 -0
  47. package/dist/utils/state.d.ts +1 -1
  48. package/dist/utils/state.js +11 -3
  49. package/dist/utils/templates.js +1 -1
  50. package/package.json +11 -4
  51. package/templates/CLAUDE.md +49 -107
  52. package/dist/agent/daemon.d.ts +0 -130
  53. package/dist/agent/daemon.js +0 -606
  54. package/dist/agent/health-check.d.ts +0 -35
  55. package/dist/agent/health-check.js +0 -243
  56. package/dist/agent/pty-runner.d.ts +0 -53
  57. package/dist/agent/pty-runner.js +0 -190
  58. package/dist/commands/agent.d.ts +0 -50
  59. package/dist/commands/agent.js +0 -544
  60. package/dist/commands/setup-remote.d.ts +0 -20
  61. package/dist/commands/setup-remote.js +0 -582
  62. package/dist/utils/verify-remote-terminal.d.ts +0 -10
  63. package/dist/utils/verify-remote-terminal.js +0 -415
  64. package/templates/README.md +0 -378
  65. package/templates/claude-plugins/PHASE2_COMPLETION.md +0 -346
  66. package/templates/claude-plugins/PLUGIN_PROPOSALS.md +0 -1776
  67. package/templates/claude-plugins/README.md +0 -587
  68. package/templates/claude-plugins/agents/code-reviewer.json +0 -14
  69. package/templates/claude-plugins/agents/debug-detective.json +0 -15
  70. package/templates/claude-plugins/agents/git-companion.json +0 -14
  71. package/templates/claude-plugins/blog-manager/.claude-plugin/plugin.json +0 -8
  72. package/templates/claude-plugins/blog-manager/commands/blog.md +0 -691
  73. package/templates/claude-plugins/golden-loop-monitor/.claude-plugin/plugin.json +0 -8
  74. package/templates/claude-plugins/golden-loop-monitor/commands/loop-status.md +0 -434
  75. package/templates/claude-plugins/learning-tracker/.claude-plugin/plugin.json +0 -8
  76. package/templates/claude-plugins/learning-tracker/commands/my-patterns.md +0 -282
  77. package/templates/claude-plugins/memory-lens/.claude-plugin/plugin.json +0 -8
  78. package/templates/claude-plugins/memory-lens/commands/memory-search.md +0 -181
  79. package/templates/claude-plugins/pattern-coach/.claude-plugin/plugin.json +0 -8
  80. package/templates/claude-plugins/pattern-coach/commands/forge.md +0 -365
  81. package/templates/claude-plugins/project-schema-validator/.claude-plugin/plugin.json +0 -8
  82. package/templates/claude-plugins/project-schema-validator/commands/validate-schema.md +0 -582
  83. package/templates/claude-plugins-admin/AGENT_TEAM_PROPOSALS.md +0 -819
  84. package/templates/claude-plugins-admin/README.md +0 -446
  85. package/templates/claude-plugins-admin/autonomous-admin-agent/.claude-plugin/plugin.json +0 -8
  86. package/templates/claude-plugins-admin/autonomous-admin-agent/commands/agent.md +0 -595
  87. package/templates/claude-plugins-admin/backend-agent/.claude-plugin/plugin.json +0 -8
  88. package/templates/claude-plugins-admin/backend-agent/commands/backend.md +0 -798
  89. package/templates/claude-plugins-admin/deploy-guardian/.claude-plugin/plugin.json +0 -8
  90. package/templates/claude-plugins-admin/deploy-guardian/commands/deploy.md +0 -554
  91. package/templates/claude-plugins-admin/frontend-agent/.claude-plugin/plugin.json +0 -8
  92. package/templates/claude-plugins-admin/frontend-agent/commands/frontend.md +0 -881
  93. package/templates/claude-plugins-admin/mcp-server-manager/.claude-plugin/plugin.json +0 -8
  94. package/templates/claude-plugins-admin/mcp-server-manager/commands/mcp.md +0 -85
  95. package/templates/claude-plugins-admin/memory-system-monitor/.claude-plugin/plugin.json +0 -8
  96. package/templates/claude-plugins-admin/memory-system-monitor/commands/memory-health.md +0 -569
  97. package/templates/claude-plugins-admin/qa-agent/.claude-plugin/plugin.json +0 -8
  98. package/templates/claude-plugins-admin/qa-agent/commands/qa.md +0 -863
  99. package/templates/claude-plugins-admin/tech-lead-agent/.claude-plugin/plugin.json +0 -8
  100. package/templates/claude-plugins-admin/tech-lead-agent/commands/lead.md +0 -732
  101. package/templates/commands/continue.md +0 -47
  102. package/templates/cursor-rules/ekkos-memory.md +0 -127
  103. package/templates/ekkos-manifest.json +0 -223
  104. package/templates/helpers/json-parse.cjs +0 -101
  105. package/templates/hooks-node/lib/state.js +0 -187
  106. package/templates/hooks-node/stop.js +0 -416
  107. package/templates/hooks-node/user-prompt-submit.js +0 -337
  108. package/templates/plan-template.md +0 -306
  109. package/templates/rules/00-hooks-contract.mdc +0 -89
  110. package/templates/rules/30-ekkos-core.mdc +0 -188
  111. package/templates/rules/31-ekkos-messages.mdc +0 -78
  112. package/templates/shared/hooks-enabled.json +0 -22
  113. package/templates/shared/session-words.json +0 -45
  114. package/templates/skills/ekkOS_Deep_Recall/Skill.md +0 -282
  115. package/templates/skills/ekkOS_Learn/Skill.md +0 -265
  116. package/templates/skills/ekkOS_Memory_First/Skill.md +0 -206
  117. package/templates/skills/ekkOS_Plan_Assist/Skill.md +0 -302
  118. package/templates/skills/ekkOS_Preferences/Skill.md +0 -247
  119. package/templates/skills/ekkOS_Reflect/Skill.md +0 -257
  120. package/templates/skills/ekkOS_Safety/Skill.md +0 -265
  121. package/templates/skills/ekkOS_Schema/Skill.md +0 -251
  122. package/templates/skills/ekkOS_Summary/Skill.md +0 -257
  123. package/templates/spec-template.md +0 -159
  124. package/templates/windsurf-rules/ekkos-memory.md +0 -127
  125. package/templates/windsurf-skills/README.md +0 -58
  126. package/templates/windsurf-skills/ekkos-continue/SKILL.md +0 -81
  127. package/templates/windsurf-skills/ekkos-golden-loop/SKILL.md +0 -225
  128. package/templates/windsurf-skills/ekkos-insights/SKILL.md +0 -138
  129. package/templates/windsurf-skills/ekkos-recall/SKILL.md +0 -96
  130. package/templates/windsurf-skills/ekkos-safety/SKILL.md +0 -89
  131. package/templates/windsurf-skills/ekkos-vault/SKILL.md +0 -86
@@ -2,11 +2,11 @@
2
2
  * ekkOS CLI: doctor command
3
3
  * Checks system prerequisites for ekkOS
4
4
  *
5
- * Per ekkOS Onboarding Spec v1.2 + Addendum:
5
+ * Gates:
6
6
  * - Node gate: Node >= 18 required (FAIL if missing)
7
+ * - Claude gate: Claude CLI installed
7
8
  * - PTY gate: WARN on Windows if missing (monitor-only mode available)
8
- * - Hooks gate: Verifies hook installation
9
- * - NO jq checks (jq dependency eliminated)
9
+ * - MCP gate: ekkOS MCP server configured
10
10
  */
11
11
  type GateStatus = 'PASS' | 'FAIL' | 'WARN';
12
12
  interface Check {
@@ -3,11 +3,11 @@
3
3
  * ekkOS CLI: doctor command
4
4
  * Checks system prerequisites for ekkOS
5
5
  *
6
- * Per ekkOS Onboarding Spec v1.2 + Addendum:
6
+ * Gates:
7
7
  * - Node gate: Node >= 18 required (FAIL if missing)
8
+ * - Claude gate: Claude CLI installed
8
9
  * - PTY gate: WARN on Windows if missing (monitor-only mode available)
9
- * - Hooks gate: Verifies hook installation
10
- * - NO jq checks (jq dependency eliminated)
10
+ * - MCP gate: ekkOS MCP server configured
11
11
  */
12
12
  var __importDefault = (this && this.__importDefault) || function (mod) {
13
13
  return (mod && mod.__esModule) ? mod : { "default": mod };
@@ -20,7 +20,6 @@ const path_1 = require("path");
20
20
  const fs_1 = require("fs");
21
21
  const child_process_1 = require("child_process");
22
22
  const chalk_1 = __importDefault(require("chalk"));
23
- const hooks_1 = require("./hooks");
24
23
  // ekkOS-managed Claude installation path (same as run.ts)
25
24
  const EKKOS_CLAUDE_BIN = (0, path_1.join)((0, os_1.homedir)(), '.ekkos', 'claude-code', 'node_modules', '.bin', 'claude');
26
25
  /**
@@ -139,44 +138,6 @@ function parseMcpOutput(output) {
139
138
  output.toLowerCase().includes('memory');
140
139
  return { configured: hasEkkos, servers };
141
140
  }
142
- /**
143
- * Check hooks installation status
144
- */
145
- function checkHooksInstallation() {
146
- const isWindows = (0, os_1.platform)() === 'win32';
147
- const manifestData = (0, hooks_1.loadManifest)();
148
- if (!manifestData) {
149
- return { installed: false, details: 'Source manifest not found' };
150
- }
151
- const platformConfig = manifestData.manifest.platforms[(0, os_1.platform)()];
152
- const globalHooksDir = (0, hooks_1.expandPath)(platformConfig.globalHooksDir);
153
- const configDir = (0, hooks_1.expandPath)(platformConfig.configDir);
154
- // Check installed manifest
155
- const installedManifestPath = (0, path_1.join)(globalHooksDir, '.ekkos-manifest.json');
156
- if (!(0, fs_1.existsSync)(installedManifestPath)) {
157
- return { installed: false, details: 'No installed manifest found' };
158
- }
159
- // Check helper
160
- const helperPath = (0, path_1.join)(configDir, '.helpers', 'json-parse.cjs');
161
- if (!(0, fs_1.existsSync)(helperPath)) {
162
- return { installed: false, details: 'json-parse.cjs helper missing' };
163
- }
164
- // Check defaults
165
- const defaultsPath = (0, path_1.join)(configDir, '.defaults', 'session-words.json');
166
- if (!(0, fs_1.existsSync)(defaultsPath)) {
167
- return { installed: false, details: 'Default session words missing' };
168
- }
169
- // Check required hooks
170
- const hookExt = isWindows ? '.ps1' : '.sh';
171
- const requiredHooks = ['user-prompt-submit', 'stop', 'session-start'];
172
- for (const hookName of requiredHooks) {
173
- const hookPath = (0, path_1.join)(globalHooksDir, `${hookName}${hookExt}`);
174
- if (!(0, fs_1.existsSync)(hookPath)) {
175
- return { installed: false, details: `${hookName}${hookExt} missing` };
176
- }
177
- }
178
- return { installed: true, details: 'All hooks and helpers installed' };
179
- }
180
141
  /**
181
142
  * Run diagnostic checks and return report
182
143
  */
@@ -266,7 +227,7 @@ function runDiagnostics() {
266
227
  ptyChecks.push({
267
228
  name: 'Monitor-only mode',
268
229
  passed: true,
269
- detail: 'Auto-continue disabled; manual /clear + /continue required'
230
+ detail: 'PTY not available on Windows; using spawn pass-through'
270
231
  });
271
232
  }
272
233
  else {
@@ -285,32 +246,11 @@ function runDiagnostics() {
285
246
  status: ptyGateStatus,
286
247
  checks: ptyChecks,
287
248
  fix: ptyGateStatus === 'WARN'
288
- ? 'npm install node-pty-prebuilt-multiarch (optional for auto-continue)'
249
+ ? 'npm install node-pty-prebuilt-multiarch (optional for terminal monitoring)'
289
250
  : undefined
290
251
  });
291
252
  // ═══════════════════════════════════════════════════════════════════════════
292
- // GATE 4: Hooks Installation (per spec v1.2)
293
- // ═══════════════════════════════════════════════════════════════════════════
294
- const hooksChecks = [];
295
- let hooksGateStatus = 'PASS';
296
- const hooksResult = checkHooksInstallation();
297
- hooksChecks.push({
298
- name: 'ekkOS hooks installed',
299
- passed: hooksResult.installed,
300
- detail: hooksResult.details
301
- });
302
- if (!hooksResult.installed) {
303
- hooksGateStatus = 'WARN';
304
- }
305
- gates.push({
306
- id: 'hooks',
307
- title: 'ekkOS Hooks',
308
- status: hooksGateStatus,
309
- checks: hooksChecks,
310
- fix: hooksGateStatus === 'WARN' ? 'ekkos hooks install --global' : undefined
311
- });
312
- // ═══════════════════════════════════════════════════════════════════════════
313
- // GATE 5: MCP Works
253
+ // GATE 4: MCP Works
314
254
  // ═══════════════════════════════════════════════════════════════════════════
315
255
  const mcpChecks = [];
316
256
  let mcpGatePass = true;
@@ -449,19 +389,6 @@ async function attemptAutoFixes(report) {
449
389
  manual.push('If that fails: Install VS Build Tools, then: npm rebuild node-pty');
450
390
  }
451
391
  break;
452
- case 'hooks':
453
- // Try to install hooks
454
- console.log(chalk_1.default.yellow('\nAttempting to install hooks...'));
455
- try {
456
- // Import and call directly
457
- const { hooksInstall } = require('./hooks');
458
- await hooksInstall({ global: true, verbose: false });
459
- fixed.push('Hooks installed');
460
- }
461
- catch {
462
- manual.push('ekkos hooks install --global');
463
- }
464
- break;
465
392
  case 'mcp':
466
393
  // Try to configure MCP (safe)
467
394
  console.log(chalk_1.default.yellow('\nAttempting to configure MCP...'));
@@ -0,0 +1,19 @@
1
+ /**
2
+ * ekkOS Gemini CLI Launcher
3
+ *
4
+ * Spawns Gemini CLI with GOOGLE_GEMINI_BASE_URL pointing at the ekkOS proxy.
5
+ * The @google/genai SDK appends /v1beta/models/{model}:generateContent to the
6
+ * base URL, which the proxy routes through IPC compression + pattern injection.
7
+ *
8
+ * Minimal wrapper — Gemini CLI handles its own terminal UX.
9
+ * Gemini CLI handles its own terminal UX.
10
+ */
11
+ export interface GeminiOptions {
12
+ verbose?: boolean;
13
+ noProxy?: boolean;
14
+ session?: string;
15
+ }
16
+ /**
17
+ * Launch Gemini CLI with ekkOS proxy integration.
18
+ */
19
+ export declare function gemini(options?: GeminiOptions): Promise<void>;
@@ -0,0 +1,193 @@
1
+ "use strict";
2
+ /**
3
+ * ekkOS Gemini CLI Launcher
4
+ *
5
+ * Spawns Gemini CLI with GOOGLE_GEMINI_BASE_URL pointing at the ekkOS proxy.
6
+ * The @google/genai SDK appends /v1beta/models/{model}:generateContent to the
7
+ * base URL, which the proxy routes through IPC compression + pattern injection.
8
+ *
9
+ * Minimal wrapper — Gemini CLI handles its own terminal UX.
10
+ * Gemini CLI handles its own terminal UX.
11
+ */
12
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ var desc = Object.getOwnPropertyDescriptor(m, k);
15
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
16
+ desc = { enumerable: true, get: function() { return m[k]; } };
17
+ }
18
+ Object.defineProperty(o, k2, desc);
19
+ }) : (function(o, m, k, k2) {
20
+ if (k2 === undefined) k2 = k;
21
+ o[k2] = m[k];
22
+ }));
23
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
24
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
25
+ }) : function(o, v) {
26
+ o["default"] = v;
27
+ });
28
+ var __importStar = (this && this.__importStar) || (function () {
29
+ var ownKeys = function(o) {
30
+ ownKeys = Object.getOwnPropertyNames || function (o) {
31
+ var ar = [];
32
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
33
+ return ar;
34
+ };
35
+ return ownKeys(o);
36
+ };
37
+ return function (mod) {
38
+ if (mod && mod.__esModule) return mod;
39
+ var result = {};
40
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
41
+ __setModuleDefault(result, mod);
42
+ return result;
43
+ };
44
+ })();
45
+ var __importDefault = (this && this.__importDefault) || function (mod) {
46
+ return (mod && mod.__esModule) ? mod : { "default": mod };
47
+ };
48
+ Object.defineProperty(exports, "__esModule", { value: true });
49
+ exports.gemini = gemini;
50
+ const chalk_1 = __importDefault(require("chalk"));
51
+ const crypto = __importStar(require("crypto"));
52
+ const path = __importStar(require("path"));
53
+ const os = __importStar(require("os"));
54
+ const fs = __importStar(require("fs"));
55
+ const child_process_1 = require("child_process");
56
+ const state_1 = require("../utils/state");
57
+ const proxy_url_1 = require("../utils/proxy-url");
58
+ // Session state — set once at startup
59
+ let cliSessionName = null;
60
+ let cliSessionId = null;
61
+ const isWindows = process.platform === 'win32';
62
+ /**
63
+ * Resolve Gemini CLI binary path.
64
+ * Checks common locations then falls back to PATH lookup.
65
+ */
66
+ function resolveGeminiPath() {
67
+ if (!isWindows) {
68
+ const pathsToCheck = [
69
+ '/opt/homebrew/bin/gemini',
70
+ '/usr/local/bin/gemini',
71
+ path.join(os.homedir(), '.local', 'bin', 'gemini'),
72
+ path.join(os.homedir(), '.npm-global', 'bin', 'gemini'),
73
+ ];
74
+ for (const p of pathsToCheck) {
75
+ if (fs.existsSync(p))
76
+ return p;
77
+ }
78
+ }
79
+ // PATH lookup
80
+ const whichCmd = isWindows ? 'where gemini' : 'which gemini';
81
+ try {
82
+ const result = (0, child_process_1.execSync)(whichCmd, { encoding: 'utf-8', stdio: 'pipe' }).trim();
83
+ if (result)
84
+ return result.split('\n')[0];
85
+ }
86
+ catch { /* not found */ }
87
+ // Fallback — let spawn resolve it (will error with helpful message)
88
+ return 'gemini';
89
+ }
90
+ /**
91
+ * Build environment for Gemini CLI with proxy routing.
92
+ */
93
+ function buildGeminiEnv(options) {
94
+ const env = { ...process.env };
95
+ if (options.noProxy) {
96
+ return env;
97
+ }
98
+ // Generate session identity (same pattern as run.ts getEkkosEnv)
99
+ if (!cliSessionName) {
100
+ cliSessionId = crypto.randomUUID();
101
+ cliSessionName = options.session || (0, state_1.uuidToWords)(cliSessionId);
102
+ console.log(chalk_1.default.gray(` 📂 Session: ${cliSessionName}`));
103
+ }
104
+ // Resolve userId from config or auth token
105
+ const ekkosConfig = (0, state_1.getConfig)();
106
+ let userId = ekkosConfig?.userId || 'anonymous';
107
+ if (userId === 'anonymous') {
108
+ const authToken = (0, state_1.getAuthToken)();
109
+ if (authToken?.startsWith('ekk_')) {
110
+ const parts = authToken.split('_');
111
+ if (parts.length >= 2 && parts[1])
112
+ userId = parts[1];
113
+ }
114
+ }
115
+ // Build proxy URL — no query params (SDK concatenates baseUrl + path as strings).
116
+ // Format: /gproxy/{userId}/{session}/{sid}/{project64}
117
+ // Proxy extracts params from path, then routes /v1beta or /v1beta1 to googleRouter.
118
+ const proxyUrl = (0, proxy_url_1.buildGeminiProxyUrl)(userId, cliSessionName, process.cwd(), cliSessionId);
119
+ env.GOOGLE_GEMINI_BASE_URL = proxyUrl;
120
+ env.GOOGLE_VERTEX_BASE_URL = proxyUrl;
121
+ // User must bring their own Gemini API key — ekkOS just proxies the traffic
122
+ // for IPC compression and pattern injection (same model as Claude).
123
+ if (!env.GEMINI_API_KEY && !env.GOOGLE_API_KEY) {
124
+ console.warn(chalk_1.default.yellow(' ⚠ GEMINI_API_KEY not set.'));
125
+ console.warn(chalk_1.default.gray(' Get one at: https://aistudio.google.com/apikey'));
126
+ console.warn(chalk_1.default.gray(' Then: export GEMINI_API_KEY=your_key'));
127
+ }
128
+ if (options.verbose) {
129
+ // Redact userId from log
130
+ const safeUrl = proxyUrl.replace(/\/proxy\/[^/]+\//, '/proxy/[user]/');
131
+ console.log(chalk_1.default.gray(` 🔗 Proxy: ${safeUrl}`));
132
+ }
133
+ return env;
134
+ }
135
+ /**
136
+ * Launch Gemini CLI with ekkOS proxy integration.
137
+ */
138
+ async function gemini(options = {}) {
139
+ (0, state_1.ensureEkkosDir)();
140
+ console.log('');
141
+ console.log(chalk_1.default.cyan(' 🧠 ekkOS_') + chalk_1.default.gray(' + ') + chalk_1.default.blue('Gemini CLI'));
142
+ // Resolve binary
143
+ const geminiPath = resolveGeminiPath();
144
+ if (options.verbose) {
145
+ console.log(chalk_1.default.gray(` 📦 Binary: ${geminiPath}`));
146
+ }
147
+ // Build env with proxy routing
148
+ const env = buildGeminiEnv(options);
149
+ // Register session for multi-session awareness
150
+ const sessionId = cliSessionId || crypto.randomUUID();
151
+ const sessionName = cliSessionName || 'gemini-session';
152
+ (0, state_1.registerActiveSession)(sessionId, sessionName, process.cwd());
153
+ if (!options.noProxy) {
154
+ console.log(chalk_1.default.cyan(' 🧠 ekkOS_Continuum Loaded!'));
155
+ }
156
+ console.log('');
157
+ // Spawn Gemini CLI — stdio: inherit for full terminal passthrough
158
+ const child = (0, child_process_1.spawn)(geminiPath, [], {
159
+ stdio: 'inherit',
160
+ env,
161
+ cwd: process.cwd(),
162
+ shell: isWindows,
163
+ });
164
+ const cleanup = () => {
165
+ (0, state_1.unregisterActiveSession)();
166
+ };
167
+ child.on('exit', (code) => {
168
+ cleanup();
169
+ if (code !== null && code !== 0) {
170
+ process.exit(code);
171
+ }
172
+ });
173
+ child.on('error', (err) => {
174
+ cleanup();
175
+ if (err.code === 'ENOENT') {
176
+ console.error('');
177
+ console.error(chalk_1.default.red(' ✘ Gemini CLI not found'));
178
+ console.error('');
179
+ console.error(chalk_1.default.white(' Install:'));
180
+ console.error(chalk_1.default.cyan(' npm install -g @google/gemini-cli'));
181
+ console.error('');
182
+ console.error(chalk_1.default.white(' Docs: ') + chalk_1.default.cyan('https://github.com/google-gemini/gemini-cli'));
183
+ console.error('');
184
+ }
185
+ else {
186
+ console.error(chalk_1.default.red(`\n ✘ Failed to launch Gemini CLI: ${err.message}\n`));
187
+ }
188
+ process.exit(1);
189
+ });
190
+ // Forward signals for clean shutdown
191
+ process.on('SIGINT', () => { child.kill('SIGINT'); });
192
+ process.on('SIGTERM', () => { child.kill('SIGTERM'); });
193
+ }
@@ -4,6 +4,7 @@ interface InitOptions {
4
4
  force?: boolean;
5
5
  skipHooks?: boolean;
6
6
  skipSkills?: boolean;
7
+ quick?: boolean;
7
8
  }
8
9
  export declare function init(options: InitOptions): Promise<void>;
9
10
  export {};
@@ -11,12 +11,10 @@ const ora_1 = __importDefault(require("ora"));
11
11
  const open_1 = __importDefault(require("open"));
12
12
  const platform_1 = require("../utils/platform");
13
13
  const mcp_1 = require("../deploy/mcp");
14
+ const settings_1 = require("../deploy/settings");
14
15
  // DEPRECATED: Hooks removed in hookless architecture migration
15
- // import { deployClaudeSettings } from '../deploy/settings';
16
16
  // import { deployHooks } from '../deploy/hooks';
17
17
  const skills_1 = require("../deploy/skills");
18
- const agents_1 = require("../deploy/agents");
19
- const plugins_1 = require("../deploy/plugins");
20
18
  const instructions_1 = require("../deploy/instructions");
21
19
  const templates_1 = require("../utils/templates");
22
20
  // ═══════════════════════════════════════════════════════════════════════════
@@ -200,23 +198,37 @@ async function manualKeyAuth(providedKey) {
200
198
  // ═══════════════════════════════════════════════════════════════════════════
201
199
  // IDE SETUP
202
200
  // ═══════════════════════════════════════════════════════════════════════════
203
- async function selectIDEs() {
201
+ async function selectIDEs(autoSelect = false) {
204
202
  console.log(chalk_1.default.cyan('Step 2/3: IDE Setup'));
205
203
  console.log(chalk_1.default.gray('─'.repeat(40)));
206
204
  console.log('');
207
205
  const detected = (0, platform_1.detectInstalledIDEs)();
208
206
  const current = (0, platform_1.detectCurrentIDE)();
209
- if (detected.length > 0) {
210
- console.log(chalk_1.default.gray(`Detected: ${detected.join(', ')}`));
207
+ // Build the unique ordered list: current IDE first, then any others detected
208
+ const detectedSet = new Set(detected);
209
+ if (current && (current === 'claude' || current === 'cursor' || current === 'windsurf')) {
210
+ detectedSet.add(current);
211
+ }
212
+ const detectedList = Array.from(detectedSet);
213
+ if (detectedList.length > 0) {
214
+ console.log(chalk_1.default.gray(`Detected: ${detectedList.join(', ')}`));
211
215
  if (current) {
212
216
  console.log(chalk_1.default.gray(`Current: ${current}`));
213
217
  }
214
218
  console.log('');
215
219
  }
220
+ // Auto-select when exactly one IDE is detected or autoSelect flag is set
221
+ if (autoSelect || detectedList.length === 1) {
222
+ const autoIDE = detectedList.length === 1 ? detectedList[0] : (current ?? detectedList[0] ?? 'claude');
223
+ const ideName = autoIDE === 'claude' ? 'Claude Code' : autoIDE === 'cursor' ? 'Cursor' : 'Windsurf';
224
+ console.log(chalk_1.default.green(`✓ Auto-detected: ${chalk_1.default.bold(ideName)}`));
225
+ console.log('');
226
+ return [autoIDE];
227
+ }
216
228
  const ideChoices = [
217
- { name: 'Claude Code', value: 'claude', checked: detected.includes('claude') || current === 'claude' },
218
- { name: 'Cursor', value: 'cursor', checked: detected.includes('cursor') || current === 'cursor' },
219
- { name: 'Windsurf (Cascade)', value: 'windsurf', checked: detected.includes('windsurf') || current === 'windsurf' }
229
+ { name: 'Claude Code', value: 'claude', checked: detectedList.includes('claude') || current === 'claude' },
230
+ { name: 'Cursor', value: 'cursor', checked: detectedList.includes('cursor') || current === 'cursor' },
231
+ { name: 'Windsurf (Cascade)', value: 'windsurf', checked: detectedList.includes('windsurf') || current === 'windsurf' }
220
232
  ];
221
233
  // If nothing was auto-detected, default to Claude Code
222
234
  if (!ideChoices.some(c => c.checked)) {
@@ -236,10 +248,7 @@ async function deployForClaude(apiKey, userId, options) {
236
248
  const result = {
237
249
  mcp: false,
238
250
  settings: false,
239
- hooks: { count: 0, files: [] },
240
251
  skills: { count: 0, skills: [] },
241
- agents: { count: 0, agents: [] },
242
- plugins: { count: 0, plugins: [] },
243
252
  instructions: false
244
253
  };
245
254
  // MCP configuration
@@ -252,11 +261,18 @@ async function deployForClaude(apiKey, userId, options) {
252
261
  catch (error) {
253
262
  spinner.fail('MCP server configuration failed');
254
263
  }
255
- // DEPRECATED: Hooks removed in hookless architecture migration
256
- // Settings.json hook registration and hook script deployment are no longer needed.
257
- // Use `ekkos run` instead.
258
- result.settings = true; // Mark as satisfied so downstream logic is unaffected
259
- // Skills
264
+ // Claude Code settings (disable auto-memory, clean up legacy hooks)
265
+ spinner = (0, ora_1.default)('Configuring Claude Code settings...').start();
266
+ try {
267
+ (0, settings_1.deployClaudeSettings)();
268
+ result.settings = true;
269
+ spinner.succeed('Claude Code settings (auto-memory disabled)');
270
+ }
271
+ catch (error) {
272
+ spinner.fail('Claude Code settings failed');
273
+ result.settings = true; // Non-critical — don't block init
274
+ }
275
+ // Skills (only continue, ekkOS_Vault, permissions — rest handled by proxy injection)
260
276
  if (!options.skipSkills) {
261
277
  spinner = (0, ora_1.default)('Deploying skills...').start();
262
278
  try {
@@ -267,24 +283,6 @@ async function deployForClaude(apiKey, userId, options) {
267
283
  spinner.fail('Skills deployment failed');
268
284
  }
269
285
  }
270
- // Agents
271
- spinner = (0, ora_1.default)('Deploying agents...').start();
272
- try {
273
- result.agents = (0, agents_1.deployAgents)();
274
- spinner.succeed(`Agents (${result.agents.count} files)`);
275
- }
276
- catch (error) {
277
- spinner.fail('Agents deployment failed');
278
- }
279
- // Plugins
280
- spinner = (0, ora_1.default)('Deploying plugins...').start();
281
- try {
282
- result.plugins = (0, plugins_1.deployPlugins)();
283
- spinner.succeed(`Plugins (${result.plugins.count} folders)`);
284
- }
285
- catch (error) {
286
- spinner.fail('Plugins deployment failed');
287
- }
288
286
  // CLAUDE.md
289
287
  spinner = (0, ora_1.default)('Deploying global instructions...').start();
290
288
  try {
@@ -325,9 +323,15 @@ async function deployForWindsurf(apiKey, userId) {
325
323
  // MAIN INIT COMMAND
326
324
  // ═══════════════════════════════════════════════════════════════════════════
327
325
  async function init(options) {
326
+ const isQuick = options.quick ?? false;
328
327
  console.log('');
329
328
  console.log(chalk_1.default.cyan.bold('╔═══════════════════════════════════════╗'));
330
- console.log(chalk_1.default.cyan.bold('║ 🧠 ekkOS Memory System Setup ║'));
329
+ if (isQuick) {
330
+ console.log(chalk_1.default.cyan.bold('║ ⚡ ekkOS Quick Setup ║'));
331
+ }
332
+ else {
333
+ console.log(chalk_1.default.cyan.bold('║ 🧠 ekkOS Memory System Setup ║'));
334
+ }
331
335
  console.log(chalk_1.default.cyan.bold('╚═══════════════════════════════════════╝'));
332
336
  console.log('');
333
337
  // Check templates exist
@@ -347,11 +351,11 @@ async function init(options) {
347
351
  // STEP 1: Authentication
348
352
  let auth;
349
353
  if (options.key) {
350
- // Manual API key provided
354
+ // Manual API key provided — always use it (respects --quick)
351
355
  auth = await manualKeyAuth(options.key);
352
356
  }
353
357
  else if (existingConfig?.apiKey && !options.force) {
354
- // Already authenticated
358
+ // Already authenticated — skip auth step entirely (works great with --quick)
355
359
  console.log(chalk_1.default.cyan('Step 1/3: Authentication'));
356
360
  console.log(chalk_1.default.gray('─'.repeat(40)));
357
361
  console.log('');
@@ -365,6 +369,10 @@ async function init(options) {
365
369
  tier: existingConfig.tier || 'unknown'
366
370
  };
367
371
  }
372
+ else if (isQuick) {
373
+ // --quick with no stored key: fall back to manual key prompt (one question only)
374
+ auth = await manualKeyAuth();
375
+ }
368
376
  else {
369
377
  // Device auth flow
370
378
  try {
@@ -395,7 +403,8 @@ async function init(options) {
395
403
  console.log('');
396
404
  }
397
405
  else {
398
- selectedIDEs = await selectIDEs();
406
+ // Pass autoSelect=true when --quick is set so we skip the checkbox prompt
407
+ selectedIDEs = await selectIDEs(isQuick);
399
408
  }
400
409
  // STEP 3: Deployment
401
410
  console.log(chalk_1.default.cyan('Step 3/3: Deploying'));
@@ -405,7 +414,7 @@ async function init(options) {
405
414
  for (const ide of selectedIDEs) {
406
415
  if (ide === 'claude') {
407
416
  const result = await deployForClaude(auth.apiKey, auth.userId, options);
408
- if (result.mcp || result.hooks.count > 0) {
417
+ if (result.mcp) {
409
418
  installedIDEs.push('claude');
410
419
  }
411
420
  }
@@ -461,7 +470,13 @@ async function init(options) {
461
470
  };
462
471
  console.log('');
463
472
  console.log(chalk_1.default.green.bold('╔═══════════════════════════════════════╗'));
464
- console.log(chalk_1.default.green.bold('║ ✓ Setup complete! ║'));
473
+ if (isQuick) {
474
+ const quickIdeName = ideNames.join(' / ') || 'Claude Code';
475
+ console.log(chalk_1.default.green.bold(`║ ⚡ Quick setup complete for ${quickIdeName.padEnd(11)}║`));
476
+ }
477
+ else {
478
+ console.log(chalk_1.default.green.bold('║ ✓ Setup complete! ║'));
479
+ }
465
480
  console.log(chalk_1.default.green.bold('╚═══════════════════════════════════════╝'));
466
481
  console.log('');
467
482
  console.log(chalk_1.default.white.bold(' MCP configured:'));
@@ -5,7 +5,6 @@ interface RunOptions {
5
5
  doctor?: boolean;
6
6
  noInject?: boolean;
7
7
  research?: boolean;
8
- noDna?: boolean;
9
8
  noProxy?: boolean;
10
9
  dashboard?: boolean;
11
10
  addDirs?: string[];