@ekkos/cli 1.3.8 → 1.4.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.
- package/LICENSE +21 -0
- package/dist/commands/dashboard.js +520 -42
- package/dist/commands/gemini.d.ts +1 -0
- package/dist/commands/gemini.js +180 -19
- package/dist/commands/init-living-docs.d.ts +6 -0
- package/dist/commands/init-living-docs.js +57 -0
- package/dist/commands/living-docs.js +3 -3
- package/dist/commands/run.d.ts +5 -0
- package/dist/commands/run.js +508 -35
- package/dist/commands/setup-ci.d.ts +3 -0
- package/dist/commands/setup-ci.js +107 -0
- package/dist/commands/validate-living-docs.d.ts +27 -0
- package/dist/commands/validate-living-docs.js +489 -0
- package/dist/index.js +97 -25
- package/dist/utils/proxy-url.d.ts +6 -1
- package/dist/utils/proxy-url.js +16 -2
- package/dist/utils/state.d.ts +16 -3
- package/dist/utils/state.js +10 -3
- package/package.json +27 -19
- package/templates/agents/prune.md +83 -0
- package/templates/agents/rewind.md +84 -0
- package/templates/agents/scout.md +102 -0
- package/templates/agents/trace.md +99 -0
- package/templates/commands/continue.md +47 -0
package/dist/commands/gemini.js
CHANGED
|
@@ -62,6 +62,8 @@ const isWindows = process.platform === 'win32';
|
|
|
62
62
|
const PULSE_LOADED_TEXT = ' 🧠 ekkOS_Pulse Loaded!';
|
|
63
63
|
const PULSE_SHINE_FRAME_MS = 50;
|
|
64
64
|
const PULSE_SHINE_SWEEPS = 2;
|
|
65
|
+
const GEMINI_DEFAULT_MODEL = 'gemini-3.1-flash-lite-preview';
|
|
66
|
+
const GEMINI_MAX_OUTPUT_TOKENS = 65536;
|
|
65
67
|
function sleep(ms) {
|
|
66
68
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
67
69
|
}
|
|
@@ -94,9 +96,18 @@ async function showPulseLoadedBanner() {
|
|
|
94
96
|
}
|
|
95
97
|
/**
|
|
96
98
|
* Resolve Gemini CLI binary path.
|
|
97
|
-
* Checks
|
|
99
|
+
* Checks PATH first (which/where), then falls back to common locations.
|
|
98
100
|
*/
|
|
99
101
|
function resolveGeminiPath() {
|
|
102
|
+
// 1. PATH lookup first to respect nvm/volta/npm-global settings
|
|
103
|
+
const whichCmd = isWindows ? 'where gemini' : 'which gemini';
|
|
104
|
+
try {
|
|
105
|
+
const result = (0, child_process_1.execSync)(whichCmd, { encoding: 'utf-8', stdio: 'pipe' }).trim();
|
|
106
|
+
if (result)
|
|
107
|
+
return result.split('\n')[0];
|
|
108
|
+
}
|
|
109
|
+
catch { /* not found in PATH */ }
|
|
110
|
+
// 2. Fallback to common global install locations
|
|
100
111
|
if (!isWindows) {
|
|
101
112
|
const pathsToCheck = [
|
|
102
113
|
'/opt/homebrew/bin/gemini',
|
|
@@ -109,16 +120,161 @@ function resolveGeminiPath() {
|
|
|
109
120
|
return p;
|
|
110
121
|
}
|
|
111
122
|
}
|
|
112
|
-
//
|
|
113
|
-
|
|
123
|
+
// 3. Ultimate fallback — let spawn resolve it (will error with helpful message)
|
|
124
|
+
return 'gemini';
|
|
125
|
+
}
|
|
126
|
+
function extractGeminiCliArgs() {
|
|
127
|
+
const geminiIdx = process.argv.indexOf('gemini');
|
|
128
|
+
if (geminiIdx === -1)
|
|
129
|
+
return [];
|
|
130
|
+
const rawArgs = process.argv.slice(geminiIdx + 1);
|
|
131
|
+
const filtered = [];
|
|
132
|
+
for (let i = 0; i < rawArgs.length; i += 1) {
|
|
133
|
+
const arg = rawArgs[i];
|
|
134
|
+
if (!arg)
|
|
135
|
+
continue;
|
|
136
|
+
if (arg === '--skip-proxy' || arg === '-v' || arg === '--verbose' || arg === '--dashboard') {
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
if (arg === '-s' || arg === '--session') {
|
|
140
|
+
i += 1;
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
filtered.push(arg);
|
|
144
|
+
}
|
|
145
|
+
return filtered;
|
|
146
|
+
}
|
|
147
|
+
function resolveGeminiLaunchModel(args) {
|
|
148
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
149
|
+
const arg = args[i];
|
|
150
|
+
if (!arg)
|
|
151
|
+
continue;
|
|
152
|
+
if ((arg === '-m' || arg === '--model') && typeof args[i + 1] === 'string') {
|
|
153
|
+
return args[i + 1];
|
|
154
|
+
}
|
|
155
|
+
if (arg.startsWith('--model=')) {
|
|
156
|
+
const value = arg.slice('--model='.length).trim();
|
|
157
|
+
if (value)
|
|
158
|
+
return value;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
const envModel = (process.env.GEMINI_MODEL || process.env.GOOGLE_GEMINI_MODEL || '').trim();
|
|
162
|
+
return envModel || GEMINI_DEFAULT_MODEL;
|
|
163
|
+
}
|
|
164
|
+
function resolveGeminiContextSize(model) {
|
|
165
|
+
const normalized = (model || '').trim().toLowerCase();
|
|
166
|
+
if (normalized.startsWith('gemini-3.1-pro') || normalized.startsWith('gemini-3-pro')) {
|
|
167
|
+
return 2097152;
|
|
168
|
+
}
|
|
169
|
+
return 1048576;
|
|
170
|
+
}
|
|
171
|
+
function resolveGeminiProjectId(projectPath) {
|
|
114
172
|
try {
|
|
115
|
-
const
|
|
116
|
-
if (
|
|
117
|
-
return
|
|
173
|
+
const projectsPath = path.join(os.homedir(), '.gemini', 'projects.json');
|
|
174
|
+
if (!fs.existsSync(projectsPath))
|
|
175
|
+
return undefined;
|
|
176
|
+
const parsed = JSON.parse(fs.readFileSync(projectsPath, 'utf-8'));
|
|
177
|
+
const projectId = parsed?.projects?.[projectPath];
|
|
178
|
+
return typeof projectId === 'string' && projectId.length > 0 ? projectId : undefined;
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
return undefined;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
function getGeminiSessionMetadata(options, args) {
|
|
185
|
+
const model = resolveGeminiLaunchModel(args);
|
|
186
|
+
return {
|
|
187
|
+
provider: 'gemini',
|
|
188
|
+
claudeModel: model,
|
|
189
|
+
claudeLaunchModel: model,
|
|
190
|
+
claudeContextWindow: '1m',
|
|
191
|
+
claudeContextSize: resolveGeminiContextSize(model),
|
|
192
|
+
claudeMaxOutputTokens: GEMINI_MAX_OUTPUT_TOKENS,
|
|
193
|
+
geminiProjectId: resolveGeminiProjectId(process.cwd()),
|
|
194
|
+
dashboardEnabled: options.dashboard === true,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
function writeGeminiSessionFiles(sessionId, sessionName, metadata) {
|
|
198
|
+
try {
|
|
199
|
+
const ekkosDir = path.join(os.homedir(), '.ekkos');
|
|
200
|
+
if (!fs.existsSync(ekkosDir))
|
|
201
|
+
fs.mkdirSync(ekkosDir, { recursive: true });
|
|
202
|
+
const now = new Date().toISOString();
|
|
203
|
+
fs.writeFileSync(path.join(ekkosDir, 'current-session.json'), JSON.stringify({ session_id: sessionId, session_name: sessionName, timestamp: now, ...metadata }, null, 2));
|
|
204
|
+
fs.writeFileSync(path.join(ekkosDir, 'session-hint.json'), JSON.stringify({
|
|
205
|
+
session_id: sessionId,
|
|
206
|
+
session_name: sessionName,
|
|
207
|
+
project_path: process.cwd(),
|
|
208
|
+
timestamp: now,
|
|
209
|
+
pid: process.pid,
|
|
210
|
+
...metadata,
|
|
211
|
+
}, null, 2));
|
|
212
|
+
}
|
|
213
|
+
catch {
|
|
214
|
+
// Non-fatal
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
function shellQuote(value) {
|
|
218
|
+
return `'${value.replace(/'/g, `'\"'\"'`)}'`;
|
|
219
|
+
}
|
|
220
|
+
function launchGeminiWithDashboard(options, extraArgs) {
|
|
221
|
+
(0, state_1.getActiveSessions)();
|
|
222
|
+
const tmuxSession = `ekkos-gemini-${Date.now().toString(36)}`;
|
|
223
|
+
const sessionName = options.session || (0, state_1.uuidToWords)(crypto.randomUUID());
|
|
224
|
+
const sessionId = crypto.randomUUID();
|
|
225
|
+
options.session = sessionName;
|
|
226
|
+
cliSessionName = sessionName;
|
|
227
|
+
cliSessionId = sessionId;
|
|
228
|
+
const metadata = getGeminiSessionMetadata({ ...options, session: sessionName, dashboard: true }, extraArgs);
|
|
229
|
+
const ekkosCmd = process.argv[1];
|
|
230
|
+
const cwd = process.cwd();
|
|
231
|
+
const termCols = process.stdout.columns ?? 160;
|
|
232
|
+
const termRows = process.stdout.rows ?? 48;
|
|
233
|
+
writeGeminiSessionFiles(sessionId, sessionName, metadata);
|
|
234
|
+
const geminiArgs = ['gemini', '-s', sessionName];
|
|
235
|
+
if (options.verbose)
|
|
236
|
+
geminiArgs.push('-v');
|
|
237
|
+
if (options.noProxy)
|
|
238
|
+
geminiArgs.push('--skip-proxy');
|
|
239
|
+
geminiArgs.push(...extraArgs);
|
|
240
|
+
const runCommand = `EKKOS_NO_SPLASH=1 node ${shellQuote(ekkosCmd)} ${geminiArgs.map(shellQuote).join(' ')}`;
|
|
241
|
+
const dashCommand = `node ${shellQuote(ekkosCmd)} dashboard ${shellQuote(sessionName)} --provider gemini --refresh 2000`;
|
|
242
|
+
try {
|
|
243
|
+
(0, child_process_1.execSync)(`tmux new-session -d -s "${tmuxSession}" -x ${termCols} -y ${termRows} -n "gemini" 'sleep 86400'`, { stdio: 'pipe' });
|
|
244
|
+
const applyTmuxOpt = (cmd) => {
|
|
245
|
+
try {
|
|
246
|
+
(0, child_process_1.execSync)(`tmux ${cmd}`, { stdio: 'pipe' });
|
|
247
|
+
}
|
|
248
|
+
catch (err) {
|
|
249
|
+
if (options.verbose) {
|
|
250
|
+
console.log(chalk_1.default.gray(` tmux option skipped: ${cmd} (${err.message})`));
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
applyTmuxOpt(`set-option -t "${tmuxSession}" default-terminal "xterm-256color"`);
|
|
255
|
+
applyTmuxOpt(`set-option -sa -t "${tmuxSession}" terminal-overrides ",xterm-256color:Tc:smcup@:rmcup@"`);
|
|
256
|
+
applyTmuxOpt(`set-option -t "${tmuxSession}" mouse on`);
|
|
257
|
+
const detachCleanupHook = `if-shell -F '#{==:#{session_attached},0}' 'kill-session -t ${tmuxSession}'`;
|
|
258
|
+
applyTmuxOpt(`set-hook -t "${tmuxSession}" client-detached "${detachCleanupHook}"`);
|
|
259
|
+
applyTmuxOpt(`set-window-option -t "${tmuxSession}" history-limit 100000`);
|
|
260
|
+
applyTmuxOpt(`set-window-option -t "${tmuxSession}" mode-keys vi`);
|
|
261
|
+
applyTmuxOpt(`set-window-option -t "${tmuxSession}:gemini" synchronize-panes off`);
|
|
262
|
+
applyTmuxOpt(`set-window-option -t "${tmuxSession}:gemini" window-size latest`);
|
|
263
|
+
applyTmuxOpt(`set-window-option -t "${tmuxSession}:gemini" aggressive-resize on`);
|
|
264
|
+
applyTmuxOpt(`set-option -t "${tmuxSession}" remain-on-exit off`);
|
|
265
|
+
applyTmuxOpt(`set-option -t "${tmuxSession}" escape-time 0`);
|
|
266
|
+
(0, child_process_1.execSync)(`tmux split-window -t "${tmuxSession}:gemini" -h -p 40 -c "${cwd}" ${shellQuote(dashCommand)}`, { stdio: 'pipe' });
|
|
267
|
+
(0, child_process_1.execSync)(`tmux respawn-pane -k -t "${tmuxSession}:gemini.0" ${shellQuote(runCommand)}`, { stdio: 'pipe' });
|
|
268
|
+
(0, child_process_1.execSync)(`tmux select-pane -t "${tmuxSession}:gemini.0"`, { stdio: 'pipe' });
|
|
269
|
+
(0, child_process_1.execSync)(`tmux attach -t "${tmuxSession}"`, { stdio: 'inherit' });
|
|
270
|
+
return true;
|
|
271
|
+
}
|
|
272
|
+
catch (err) {
|
|
273
|
+
console.error(chalk_1.default.red(`\n ✘ Failed to launch Gemini dashboard split: ${err.message}\n`));
|
|
274
|
+
console.log(chalk_1.default.gray(' Falling back to normal Gemini mode.'));
|
|
275
|
+
console.log(chalk_1.default.gray(' Run "ekkos dashboard --latest --provider gemini" in another terminal.\n'));
|
|
276
|
+
return false;
|
|
118
277
|
}
|
|
119
|
-
catch { /* not found */ }
|
|
120
|
-
// Fallback — let spawn resolve it (will error with helpful message)
|
|
121
|
-
return 'gemini';
|
|
122
278
|
}
|
|
123
279
|
/**
|
|
124
280
|
* Build environment for Gemini CLI with proxy routing.
|
|
@@ -137,14 +293,20 @@ function buildGeminiEnv(options) {
|
|
|
137
293
|
// Resolve userId from config or auth token
|
|
138
294
|
const ekkosConfig = (0, state_1.getConfig)();
|
|
139
295
|
let userId = ekkosConfig?.userId || 'anonymous';
|
|
296
|
+
const authToken = (0, state_1.getAuthToken)();
|
|
140
297
|
if (userId === 'anonymous') {
|
|
141
|
-
const authToken = (0, state_1.getAuthToken)();
|
|
142
298
|
if (authToken?.startsWith('ekk_')) {
|
|
143
299
|
const parts = authToken.split('_');
|
|
144
300
|
if (parts.length >= 2 && parts[1])
|
|
145
301
|
userId = parts[1];
|
|
146
302
|
}
|
|
147
303
|
}
|
|
304
|
+
// Gemini CLI strictly requires an API key to exist in the environment,
|
|
305
|
+
// even when routing to a proxy. If they don't have GEMINI_API_KEY set,
|
|
306
|
+
// provide their GOOGLE_AI_API_KEY, ekkOS auth token, or a placeholder so the CLI boots up.
|
|
307
|
+
if (!env.GEMINI_API_KEY) {
|
|
308
|
+
env.GEMINI_API_KEY = env.GOOGLE_AI_API_KEY || authToken || 'ekk_guest_token_for_proxy';
|
|
309
|
+
}
|
|
148
310
|
// Build proxy URL — no query params (SDK concatenates baseUrl + path as strings).
|
|
149
311
|
// Format: /gproxy/{userId}/{session}/{sid}/{project64}
|
|
150
312
|
// Proxy extracts params from path, then routes /v1beta or /v1beta1 to googleRouter.
|
|
@@ -163,6 +325,11 @@ function buildGeminiEnv(options) {
|
|
|
163
325
|
*/
|
|
164
326
|
async function gemini(options = {}) {
|
|
165
327
|
(0, state_1.ensureEkkosDir)();
|
|
328
|
+
const extraArgs = extractGeminiCliArgs();
|
|
329
|
+
if (options.dashboard) {
|
|
330
|
+
if (launchGeminiWithDashboard(options, extraArgs))
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
166
333
|
console.log('');
|
|
167
334
|
console.log(chalk_1.default.cyan(' 🧠 ekkOS_') + chalk_1.default.gray(' + ') + chalk_1.default.blue('Gemini CLI'));
|
|
168
335
|
// Resolve binary
|
|
@@ -175,7 +342,9 @@ async function gemini(options = {}) {
|
|
|
175
342
|
// Register session for multi-session awareness
|
|
176
343
|
const sessionId = cliSessionId || crypto.randomUUID();
|
|
177
344
|
const sessionName = cliSessionName || 'gemini-session';
|
|
178
|
-
|
|
345
|
+
const metadata = getGeminiSessionMetadata(options, extraArgs);
|
|
346
|
+
(0, state_1.registerActiveSession)(sessionId, sessionName, process.cwd(), metadata);
|
|
347
|
+
writeGeminiSessionFiles(sessionId, sessionName, metadata);
|
|
179
348
|
if (!options.noProxy) {
|
|
180
349
|
await showPulseLoadedBanner();
|
|
181
350
|
}
|
|
@@ -183,14 +352,6 @@ async function gemini(options = {}) {
|
|
|
183
352
|
// Extract any trailing arguments meant for the inner CLI
|
|
184
353
|
// We look for 'gemini' in process.argv and pass everything after it.
|
|
185
354
|
// If the user did `ekkos gemini -m gemini-3.1-pro-preview`, we want to pass `-m gemini-3.1-pro-preview`
|
|
186
|
-
let extraArgs = [];
|
|
187
|
-
const geminiIdx = process.argv.indexOf('gemini');
|
|
188
|
-
if (geminiIdx !== -1) {
|
|
189
|
-
extraArgs = process.argv.slice(geminiIdx + 1).filter(a => {
|
|
190
|
-
// Filter out ekkos wrapper options
|
|
191
|
-
return !['--skip-proxy', '-v', '--verbose'].includes(a) && !(a === '-s' || a === '--session' || process.argv[process.argv.indexOf(a) - 1] === '-s' || process.argv[process.argv.indexOf(a) - 1] === '--session');
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
355
|
// Spawn Gemini CLI — stdio: inherit for full terminal passthrough
|
|
195
356
|
const child = (0, child_process_1.spawn)(geminiPath, extraArgs, {
|
|
196
357
|
stdio: 'inherit',
|
|
@@ -0,0 +1,57 @@
|
|
|
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.initLivingDocs = initLivingDocs;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const path_1 = require("path");
|
|
9
|
+
const living_docs_manager_js_1 = require("../local/living-docs-manager.js");
|
|
10
|
+
const state_1 = require("../utils/state");
|
|
11
|
+
const platform_js_1 = require("../utils/platform.js");
|
|
12
|
+
async function initLivingDocs(options) {
|
|
13
|
+
const targetPath = (0, path_1.resolve)(options.path || process.cwd());
|
|
14
|
+
const timeZone = options.timeZone || process.env.EKKOS_USER_TIMEZONE || Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
15
|
+
const apiKey = options.noSeed ? null : (0, state_1.getAuthToken)();
|
|
16
|
+
const apiUrl = options.noSeed ? undefined : (process.env.EKKOS_API_URL || platform_js_1.MCP_API_URL);
|
|
17
|
+
console.log('\n ' + chalk_1.default.cyan.bold('Initialize ekkOS Cortex'));
|
|
18
|
+
console.log(chalk_1.default.gray(' ─────────────────────────────────'));
|
|
19
|
+
console.log(chalk_1.default.gray(` Path: ${targetPath}`));
|
|
20
|
+
const manager = new living_docs_manager_js_1.LocalLivingDocsManager({
|
|
21
|
+
targetPath,
|
|
22
|
+
apiUrl,
|
|
23
|
+
apiKey,
|
|
24
|
+
timeZone,
|
|
25
|
+
onLog: message => console.log(chalk_1.default.gray(` ${message}`)),
|
|
26
|
+
});
|
|
27
|
+
// Force a full scan and compile by ignoring the cooldown
|
|
28
|
+
// We'll use a slightly different flow than .start() to make it one-shot
|
|
29
|
+
console.log(chalk_1.default.gray(' Scanning repository structure...'));
|
|
30
|
+
// We hack the cooldown by temporarily setting the env var if we could,
|
|
31
|
+
// but better to just call the internal methods if they were public.
|
|
32
|
+
// Since they are private, we'll use a small trick:
|
|
33
|
+
// The start() method is what we want, but we want it to exit after the first pass.
|
|
34
|
+
// Actually, let's just use start() and wait for the initialCompilePromise
|
|
35
|
+
manager.start();
|
|
36
|
+
// Give it a moment to start the initial pass
|
|
37
|
+
const checkInterval = setInterval(() => {
|
|
38
|
+
// @ts-ignore - reaching into private for the promise
|
|
39
|
+
if (manager.initialCompilePromise) {
|
|
40
|
+
// @ts-ignore
|
|
41
|
+
manager.initialCompilePromise.then(() => {
|
|
42
|
+
clearInterval(checkInterval);
|
|
43
|
+
manager.stop();
|
|
44
|
+
console.log('\n' + chalk_1.default.green(' ✓ ekkOS Cortex initialized successfully!'));
|
|
45
|
+
console.log(chalk_1.default.gray(' Your project now has ekkOS_CONTEXT.md files for every discovered system.'));
|
|
46
|
+
console.log(chalk_1.default.gray(' Run `ekkos cortex watch` to keep them updated while you work.'));
|
|
47
|
+
console.log('');
|
|
48
|
+
process.exit(0);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}, 100);
|
|
52
|
+
// Safety timeout
|
|
53
|
+
setTimeout(() => {
|
|
54
|
+
console.log(chalk_1.default.red('\n Initialization timed out.'));
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}, 60000);
|
|
57
|
+
}
|
|
@@ -11,13 +11,13 @@ const state_1 = require("../utils/state");
|
|
|
11
11
|
const platform_js_1 = require("../utils/platform.js");
|
|
12
12
|
function printStartupSummary(options) {
|
|
13
13
|
console.log('');
|
|
14
|
-
console.log(chalk_1.default.cyan.bold(' ekkOS
|
|
15
|
-
console.log(chalk_1.default.gray('
|
|
14
|
+
console.log(chalk_1.default.cyan.bold(' ekkOS Cortex Watcher'));
|
|
15
|
+
console.log(chalk_1.default.gray(' ──────────────────────'));
|
|
16
16
|
console.log(chalk_1.default.gray(` Path: ${options.targetPath}`));
|
|
17
17
|
console.log(chalk_1.default.gray(` Timezone: ${options.timeZone}`));
|
|
18
18
|
console.log(chalk_1.default.gray(` Registry seed: ${options.seedingEnabled ? 'enabled' : 'disabled'}`));
|
|
19
19
|
console.log('');
|
|
20
|
-
console.log(chalk_1.default.gray(' Watching local files and
|
|
20
|
+
console.log(chalk_1.default.gray(' Watching local files and updating Cortex docs (ekkOS_CONTEXT.md) on change.'));
|
|
21
21
|
console.log(chalk_1.default.gray(' Press Ctrl+C to stop.'));
|
|
22
22
|
console.log('');
|
|
23
23
|
}
|
package/dist/commands/run.d.ts
CHANGED
|
@@ -2,12 +2,17 @@ interface RunOptions {
|
|
|
2
2
|
session?: string;
|
|
3
3
|
verbose?: boolean;
|
|
4
4
|
bypass?: boolean;
|
|
5
|
+
pulse?: boolean;
|
|
5
6
|
doctor?: boolean;
|
|
6
7
|
noInject?: boolean;
|
|
7
8
|
research?: boolean;
|
|
8
9
|
noProxy?: boolean;
|
|
9
10
|
dashboard?: boolean;
|
|
10
11
|
addDirs?: string[];
|
|
12
|
+
model?: string | boolean;
|
|
13
|
+
contextWindow?: string;
|
|
14
|
+
continueLast?: boolean;
|
|
15
|
+
resumeSession?: string;
|
|
11
16
|
slashOpenDelayMs?: number;
|
|
12
17
|
charDelayMs?: number;
|
|
13
18
|
postEnterDelayMs?: number;
|