@ekkos/cli 1.0.34 → 1.0.35
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/dist/capture/jsonl-rewriter.js +72 -7
- package/dist/commands/dashboard.js +186 -557
- package/dist/commands/init.js +3 -15
- package/dist/commands/run.js +222 -256
- package/dist/commands/setup.js +0 -47
- package/dist/commands/swarm-dashboard.js +4 -13
- package/dist/deploy/instructions.d.ts +2 -5
- package/dist/deploy/instructions.js +8 -11
- package/dist/deploy/settings.js +21 -15
- package/dist/deploy/skills.d.ts +0 -8
- package/dist/deploy/skills.js +0 -26
- package/dist/index.js +2 -2
- package/dist/lib/usage-parser.js +1 -2
- package/dist/utils/platform.d.ts +0 -3
- package/dist/utils/platform.js +1 -4
- package/dist/utils/session-binding.d.ts +1 -1
- package/dist/utils/session-binding.js +2 -3
- package/package.json +4 -2
- package/templates/CLAUDE.md +23 -135
- package/templates/agents/README.md +182 -0
- package/templates/agents/code-reviewer.md +166 -0
- package/templates/agents/debug-detective.md +169 -0
- package/templates/agents/ekkOS_Vercel.md +99 -0
- package/templates/agents/extension-manager.md +229 -0
- package/templates/agents/git-companion.md +185 -0
- package/templates/agents/github-test-agent.md +321 -0
- package/templates/agents/railway-manager.md +179 -0
- package/templates/ekkos-manifest.json +8 -8
- package/templates/hooks/assistant-response.ps1 +160 -256
- package/templates/hooks/assistant-response.sh +66 -130
- package/templates/hooks/hooks.json +0 -6
- package/templates/hooks/lib/contract.sh +31 -43
- package/templates/hooks/lib/count-tokens.cjs +0 -0
- package/templates/hooks/lib/ekkos-reminders.sh +0 -0
- package/templates/hooks/lib/state.sh +1 -53
- package/templates/hooks/session-start.ps1 +391 -91
- package/templates/hooks/session-start.sh +166 -201
- package/templates/hooks/stop.ps1 +341 -202
- package/templates/hooks/stop.sh +948 -275
- package/templates/hooks/user-prompt-submit.ps1 +548 -224
- package/templates/hooks/user-prompt-submit.sh +456 -382
- package/templates/plan-template.md +0 -0
- package/templates/spec-template.md +0 -0
- package/templates/windsurf-hooks/before-submit-prompt.sh +238 -0
- package/templates/windsurf-hooks/hooks.json +2 -9
- package/templates/windsurf-hooks/install.sh +0 -0
- package/templates/windsurf-hooks/lib/contract.sh +0 -2
- package/templates/windsurf-hooks/post-cascade-response.sh +0 -0
- package/templates/windsurf-hooks/pre-user-prompt.sh +0 -0
- package/templates/windsurf-skills/ekkos-memory/SKILL.md +219 -0
- package/README.md +0 -57
package/dist/commands/setup.js
CHANGED
|
@@ -1,37 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
4
|
};
|
|
@@ -384,20 +351,6 @@ async function setupWindsurf(apiKey) {
|
|
|
384
351
|
(0, fs_1.mkdirSync)(windsurfDir, { recursive: true });
|
|
385
352
|
}
|
|
386
353
|
(0, fs_1.writeFileSync)((0, path_1.join)(windsurfDir, 'ekkos.json'), JSON.stringify({ apiKey }, null, 2));
|
|
387
|
-
// Deploy Windsurf skills (Agent Skills spec — 6 Golden Loop skills)
|
|
388
|
-
const skillsDir = (0, path_1.join)(codeiumDir, 'skills');
|
|
389
|
-
if (!(0, fs_1.existsSync)(skillsDir)) {
|
|
390
|
-
(0, fs_1.mkdirSync)(skillsDir, { recursive: true });
|
|
391
|
-
}
|
|
392
|
-
try {
|
|
393
|
-
const { deployWindsurfSkills } = await Promise.resolve().then(() => __importStar(require('../deploy/skills.js')));
|
|
394
|
-
const result = deployWindsurfSkills();
|
|
395
|
-
console.log(chalk_1.default.green(` ✓ Deployed ${result.count} skills: ${result.skills.join(', ')}`));
|
|
396
|
-
}
|
|
397
|
-
catch {
|
|
398
|
-
// Fallback: templates might not be available in setup path
|
|
399
|
-
console.log(chalk_1.default.yellow(' Note: Skills templates not found. Run `ekkos init --ide windsurf` to deploy skills.'));
|
|
400
|
-
}
|
|
401
354
|
// Create project rules template
|
|
402
355
|
const cascadeRules = generateCascadeRules();
|
|
403
356
|
const cascadeRulesPath = (0, path_1.join)(process.cwd(), '.windsurfrules');
|
|
@@ -582,19 +582,10 @@ async function launchSwarmDashboard(launchTs, refreshMs) {
|
|
|
582
582
|
// ── Usage window (Anthropic OAuth) ──
|
|
583
583
|
async function fetchAnthropicUsage() {
|
|
584
584
|
try {
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
token = JSON.parse(credsJson)?.claudeAiOauth?.accessToken ?? null;
|
|
590
|
-
}
|
|
591
|
-
else if (process.platform === 'win32') {
|
|
592
|
-
const credsPath = path.join(os.homedir(), '.claude', '.credentials.json');
|
|
593
|
-
if (require('fs').existsSync(credsPath)) {
|
|
594
|
-
const creds = JSON.parse(require('fs').readFileSync(credsPath, 'utf-8'));
|
|
595
|
-
token = creds?.claudeAiOauth?.accessToken ?? null;
|
|
596
|
-
}
|
|
597
|
-
}
|
|
585
|
+
const { execSync } = require('child_process');
|
|
586
|
+
const credsJson = execSync('security find-generic-password -s "Claude Code-credentials" -w', { encoding: 'utf-8', timeout: 5000 }).trim();
|
|
587
|
+
const creds = JSON.parse(credsJson);
|
|
588
|
+
const token = creds?.claudeAiOauth?.accessToken;
|
|
598
589
|
if (!token)
|
|
599
590
|
return null;
|
|
600
591
|
const resp = await fetch('https://api.anthropic.com/api/oauth/usage', {
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Deploy
|
|
3
|
-
*
|
|
4
|
-
* Uses Claude Code's user-level rules directory — auto-loaded for all projects
|
|
5
|
-
* without touching the user's existing CLAUDE.md.
|
|
2
|
+
* Deploy CLAUDE.md to ~/.claude/CLAUDE.md
|
|
6
3
|
*/
|
|
7
4
|
export declare function deployInstructions(): void;
|
|
8
5
|
/**
|
|
9
|
-
* Check if
|
|
6
|
+
* Check if CLAUDE.md is deployed
|
|
10
7
|
*/
|
|
11
8
|
export declare function isInstructionsDeployed(): boolean;
|
|
12
9
|
/**
|
|
@@ -7,24 +7,21 @@ const fs_1 = require("fs");
|
|
|
7
7
|
const platform_1 = require("../utils/platform");
|
|
8
8
|
const templates_1 = require("../utils/templates");
|
|
9
9
|
/**
|
|
10
|
-
* Deploy
|
|
11
|
-
*
|
|
12
|
-
* Uses Claude Code's user-level rules directory — auto-loaded for all projects
|
|
13
|
-
* without touching the user's existing CLAUDE.md.
|
|
10
|
+
* Deploy CLAUDE.md to ~/.claude/CLAUDE.md
|
|
14
11
|
*/
|
|
15
12
|
function deployInstructions() {
|
|
16
|
-
// Ensure
|
|
17
|
-
if (!(0, fs_1.existsSync)(platform_1.
|
|
18
|
-
(0, fs_1.mkdirSync)(platform_1.
|
|
13
|
+
// Ensure .claude directory exists
|
|
14
|
+
if (!(0, fs_1.existsSync)(platform_1.CLAUDE_DIR)) {
|
|
15
|
+
(0, fs_1.mkdirSync)(platform_1.CLAUDE_DIR, { recursive: true });
|
|
19
16
|
}
|
|
20
|
-
//
|
|
21
|
-
(0, templates_1.copyTemplateFile)('CLAUDE.md', platform_1.
|
|
17
|
+
// Copy CLAUDE.md template
|
|
18
|
+
(0, templates_1.copyTemplateFile)('CLAUDE.md', platform_1.CLAUDE_MD);
|
|
22
19
|
}
|
|
23
20
|
/**
|
|
24
|
-
* Check if
|
|
21
|
+
* Check if CLAUDE.md is deployed
|
|
25
22
|
*/
|
|
26
23
|
function isInstructionsDeployed() {
|
|
27
|
-
return (0, fs_1.existsSync)(platform_1.
|
|
24
|
+
return (0, fs_1.existsSync)(platform_1.CLAUDE_MD);
|
|
28
25
|
}
|
|
29
26
|
/**
|
|
30
27
|
* Get the CLAUDE.md content (for preview)
|
package/dist/deploy/settings.js
CHANGED
|
@@ -3,38 +3,43 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.deployClaudeSettings = deployClaudeSettings;
|
|
4
4
|
exports.areHooksConfigured = areHooksConfigured;
|
|
5
5
|
const fs_1 = require("fs");
|
|
6
|
-
const path_1 = require("path");
|
|
7
6
|
const platform_1 = require("../utils/platform");
|
|
8
7
|
/**
|
|
9
8
|
* Generate the hooks configuration for Claude Code settings.json
|
|
10
|
-
* Uses the new format required by Claude Code 2.1.40+
|
|
11
9
|
*/
|
|
12
10
|
function generateHooksConfig() {
|
|
13
|
-
|
|
14
|
-
// JSON.stringify handles backslash-escaping automatically — do NOT pre-escape.
|
|
15
|
-
//
|
|
16
|
-
// IMPORTANT: Do NOT use `-File` on Windows — Claude Code has a known bug where
|
|
17
|
-
// it fails to canonicalize absolute script paths, producing "system cannot find
|
|
18
|
-
// the specified path". Use `-Command "& 'path'"` instead, which bypasses it.
|
|
19
|
-
// See: https://github.com/anthropics/claude-code/issues/12874
|
|
11
|
+
const hooksDir = `${platform_1.HOME_DIR}/.claude/hooks`;
|
|
20
12
|
if (platform_1.isWindows) {
|
|
13
|
+
// Windows uses PowerShell
|
|
21
14
|
return {
|
|
15
|
+
SessionStart: [
|
|
16
|
+
{ type: 'command', command: `powershell -ExecutionPolicy Bypass -File "${hooksDir}/session-start.ps1"` }
|
|
17
|
+
],
|
|
22
18
|
UserPromptSubmit: [
|
|
23
|
-
{
|
|
19
|
+
{ type: 'command', command: `powershell -ExecutionPolicy Bypass -File "${hooksDir}/user-prompt-submit.ps1"` }
|
|
24
20
|
],
|
|
25
21
|
Stop: [
|
|
26
|
-
{
|
|
22
|
+
{ type: 'command', command: `powershell -ExecutionPolicy Bypass -File "${hooksDir}/stop.ps1"` }
|
|
27
23
|
],
|
|
24
|
+
AssistantResponse: [
|
|
25
|
+
{ type: 'command', command: `powershell -ExecutionPolicy Bypass -File "${hooksDir}/assistant-response.ps1"` }
|
|
26
|
+
]
|
|
28
27
|
};
|
|
29
28
|
}
|
|
30
|
-
// Unix
|
|
29
|
+
// Unix uses bash
|
|
31
30
|
return {
|
|
31
|
+
SessionStart: [
|
|
32
|
+
{ type: 'command', command: `bash ${hooksDir}/session-start.sh` }
|
|
33
|
+
],
|
|
32
34
|
UserPromptSubmit: [
|
|
33
|
-
{
|
|
35
|
+
{ type: 'command', command: `bash ${hooksDir}/user-prompt-submit.sh` }
|
|
34
36
|
],
|
|
35
37
|
Stop: [
|
|
36
|
-
{
|
|
38
|
+
{ type: 'command', command: `bash ${hooksDir}/stop.sh` }
|
|
37
39
|
],
|
|
40
|
+
AssistantResponse: [
|
|
41
|
+
{ type: 'command', command: `bash ${hooksDir}/assistant-response.sh` }
|
|
42
|
+
]
|
|
38
43
|
};
|
|
39
44
|
}
|
|
40
45
|
/**
|
|
@@ -69,7 +74,8 @@ function areHooksConfigured() {
|
|
|
69
74
|
try {
|
|
70
75
|
const settings = JSON.parse((0, fs_1.readFileSync)(platform_1.CLAUDE_SETTINGS, 'utf-8'));
|
|
71
76
|
const hooks = settings.hooks || {};
|
|
72
|
-
return Boolean(hooks.
|
|
77
|
+
return Boolean(hooks.SessionStart?.length &&
|
|
78
|
+
hooks.UserPromptSubmit?.length &&
|
|
73
79
|
hooks.Stop?.length);
|
|
74
80
|
}
|
|
75
81
|
catch {
|
package/dist/deploy/skills.d.ts
CHANGED
|
@@ -5,14 +5,6 @@ export declare function deploySkills(): {
|
|
|
5
5
|
count: number;
|
|
6
6
|
skills: string[];
|
|
7
7
|
};
|
|
8
|
-
/**
|
|
9
|
-
* Deploy Windsurf skills to ~/.codeium/windsurf/skills/
|
|
10
|
-
* Uses Agent Skills spec format (lowercase-hyphenated names, SKILL.md)
|
|
11
|
-
*/
|
|
12
|
-
export declare function deployWindsurfSkills(): {
|
|
13
|
-
count: number;
|
|
14
|
-
skills: string[];
|
|
15
|
-
};
|
|
16
8
|
/**
|
|
17
9
|
* Check if skills are deployed
|
|
18
10
|
*/
|
package/dist/deploy/skills.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.deploySkills = deploySkills;
|
|
4
|
-
exports.deployWindsurfSkills = deployWindsurfSkills;
|
|
5
4
|
exports.areSkillsDeployed = areSkillsDeployed;
|
|
6
5
|
exports.countDeployedSkills = countDeployedSkills;
|
|
7
6
|
exports.listExpectedSkills = listExpectedSkills;
|
|
@@ -33,31 +32,6 @@ function deploySkills() {
|
|
|
33
32
|
skills: deployedSkills
|
|
34
33
|
};
|
|
35
34
|
}
|
|
36
|
-
/**
|
|
37
|
-
* Deploy Windsurf skills to ~/.codeium/windsurf/skills/
|
|
38
|
-
* Uses Agent Skills spec format (lowercase-hyphenated names, SKILL.md)
|
|
39
|
-
*/
|
|
40
|
-
function deployWindsurfSkills() {
|
|
41
|
-
if (!(0, fs_1.existsSync)(platform_1.WINDSURF_SKILLS_DIR)) {
|
|
42
|
-
(0, fs_1.mkdirSync)(platform_1.WINDSURF_SKILLS_DIR, { recursive: true });
|
|
43
|
-
}
|
|
44
|
-
const skillNames = (0, templates_1.listTemplateDirs)('windsurf-skills');
|
|
45
|
-
const deployedSkills = [];
|
|
46
|
-
for (const skillName of skillNames) {
|
|
47
|
-
try {
|
|
48
|
-
const destPath = `${platform_1.WINDSURF_SKILLS_DIR}/${skillName}`;
|
|
49
|
-
(0, templates_1.copyTemplateDir)(`windsurf-skills/${skillName}`, destPath);
|
|
50
|
-
deployedSkills.push(skillName);
|
|
51
|
-
}
|
|
52
|
-
catch (error) {
|
|
53
|
-
console.warn(`Warning: Could not deploy Windsurf skill ${skillName}`);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
return {
|
|
57
|
-
count: deployedSkills.length,
|
|
58
|
-
skills: deployedSkills
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
35
|
/**
|
|
62
36
|
* Check if skills are deployed
|
|
63
37
|
*/
|
package/dist/index.js
CHANGED
|
@@ -246,10 +246,10 @@ commander_1.program
|
|
|
246
246
|
.option('-d, --doctor', 'Run diagnostics before starting')
|
|
247
247
|
.option('-r, --research', 'Auto-run research agent on startup (scans arXiv for new AI papers)')
|
|
248
248
|
.option('--skip-inject', 'Monitor-only mode (detect context wall but print instructions instead of auto-inject)')
|
|
249
|
-
.option('--skip-dna', '
|
|
249
|
+
.option('--skip-dna', 'Skip ccDNA injection (bypass Claude Code patching)')
|
|
250
250
|
.option('--skip-proxy', 'Skip API proxy (use direct Anthropic API, disables seamless context eviction)')
|
|
251
251
|
.option('--dashboard', 'Launch with live usage dashboard in an isolated 60/40 tmux split (requires tmux)')
|
|
252
|
-
.option('--kickstart', 'Auto-send "test" on load to create session immediately (
|
|
252
|
+
.option('--kickstart', 'Auto-send "test" on load to create session immediately (used internally by --dashboard)')
|
|
253
253
|
.option('--add-dir <dirs...>', 'Additional directories Claude Code can access (outside working directory)')
|
|
254
254
|
.action((options) => {
|
|
255
255
|
(0, run_1.run)({
|
package/dist/lib/usage-parser.js
CHANGED
|
@@ -79,8 +79,7 @@ function isEkkosSessionName(name) {
|
|
|
79
79
|
return /^[a-z]+-[a-z]+-[a-z]+$/.test(name);
|
|
80
80
|
}
|
|
81
81
|
function encodeProjectPath(projectPath) {
|
|
82
|
-
|
|
83
|
-
return projectPath.replace(/[:\\/]/g, '-');
|
|
82
|
+
return projectPath.replace(/\//g, '-');
|
|
84
83
|
}
|
|
85
84
|
/** Resolve an ekkOS session name to a JSONL UUID */
|
|
86
85
|
function resolveSessionName(name) {
|
package/dist/utils/platform.d.ts
CHANGED
|
@@ -15,13 +15,10 @@ export declare const CLAUDE_AGENTS_DIR: string;
|
|
|
15
15
|
export declare const CLAUDE_PLUGINS_DIR: string;
|
|
16
16
|
export declare const CLAUDE_STATE_DIR: string;
|
|
17
17
|
export declare const CLAUDE_MD: string;
|
|
18
|
-
export declare const CLAUDE_RULES_DIR: string;
|
|
19
|
-
export declare const CLAUDE_EKKOS_RULES: string;
|
|
20
18
|
export declare const CURSOR_DIR: string;
|
|
21
19
|
export declare const CURSOR_MCP: string;
|
|
22
20
|
export declare const WINDSURF_DIR: string;
|
|
23
21
|
export declare const WINDSURF_MCP: string;
|
|
24
|
-
export declare const WINDSURF_SKILLS_DIR: string;
|
|
25
22
|
/**
|
|
26
23
|
* Detect which IDEs are installed on this system
|
|
27
24
|
*/
|
package/dist/utils/platform.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.WINDSURF_MCP = exports.WINDSURF_DIR = exports.CURSOR_MCP = exports.CURSOR_DIR = exports.CLAUDE_MD = exports.CLAUDE_STATE_DIR = exports.CLAUDE_PLUGINS_DIR = exports.CLAUDE_AGENTS_DIR = exports.CLAUDE_SKILLS_DIR = exports.CLAUDE_HOOKS_DIR = exports.CLAUDE_SETTINGS = exports.CLAUDE_CONFIG = exports.CLAUDE_DIR = exports.EKKOS_CONFIG = exports.EKKOS_DIR = exports.HOME_DIR = exports.MCP_API_URL = exports.PLATFORM_URL = exports.isLinux = exports.isMac = exports.isWindows = void 0;
|
|
4
4
|
exports.detectInstalledIDEs = detectInstalledIDEs;
|
|
5
5
|
exports.detectCurrentIDE = detectCurrentIDE;
|
|
6
6
|
const os_1 = require("os");
|
|
@@ -24,13 +24,10 @@ exports.CLAUDE_AGENTS_DIR = (0, path_1.join)(exports.CLAUDE_DIR, 'agents');
|
|
|
24
24
|
exports.CLAUDE_PLUGINS_DIR = (0, path_1.join)(exports.CLAUDE_DIR, 'plugins', 'ekkos');
|
|
25
25
|
exports.CLAUDE_STATE_DIR = (0, path_1.join)(exports.CLAUDE_DIR, 'state');
|
|
26
26
|
exports.CLAUDE_MD = (0, path_1.join)(exports.CLAUDE_DIR, 'CLAUDE.md');
|
|
27
|
-
exports.CLAUDE_RULES_DIR = (0, path_1.join)(exports.CLAUDE_DIR, 'rules');
|
|
28
|
-
exports.CLAUDE_EKKOS_RULES = (0, path_1.join)(exports.CLAUDE_RULES_DIR, 'ekkos.md');
|
|
29
27
|
exports.CURSOR_DIR = (0, path_1.join)(exports.HOME_DIR, '.cursor');
|
|
30
28
|
exports.CURSOR_MCP = (0, path_1.join)(exports.CURSOR_DIR, 'mcp.json');
|
|
31
29
|
exports.WINDSURF_DIR = (0, path_1.join)(exports.HOME_DIR, '.codeium', 'windsurf');
|
|
32
30
|
exports.WINDSURF_MCP = (0, path_1.join)(exports.WINDSURF_DIR, 'mcp_config.json');
|
|
33
|
-
exports.WINDSURF_SKILLS_DIR = (0, path_1.join)(exports.WINDSURF_DIR, 'skills');
|
|
34
31
|
/**
|
|
35
32
|
* Detect which IDEs are installed on this system
|
|
36
33
|
*/
|
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
* Bind the real session name to the proxy
|
|
3
3
|
* This replaces the '_pending' placeholder for this user, enabling proper eviction
|
|
4
4
|
*/
|
|
5
|
-
export declare function bindSession(realSession: string, projectPath: string
|
|
5
|
+
export declare function bindSession(realSession: string, projectPath: string): Promise<boolean>;
|
|
@@ -7,7 +7,7 @@ const MEMORY_API_URL = process.env.EKKOS_PROXY_URL || 'https://proxy.ekkos.dev';
|
|
|
7
7
|
* Bind the real session name to the proxy
|
|
8
8
|
* This replaces the '_pending' placeholder for this user, enabling proper eviction
|
|
9
9
|
*/
|
|
10
|
-
async function bindSession(realSession, projectPath
|
|
10
|
+
async function bindSession(realSession, projectPath) {
|
|
11
11
|
try {
|
|
12
12
|
// Get userId same way as run.ts
|
|
13
13
|
const config = (0, state_1.getConfig)();
|
|
@@ -33,8 +33,7 @@ async function bindSession(realSession, projectPath, pendingSession) {
|
|
|
33
33
|
body: JSON.stringify({
|
|
34
34
|
userId,
|
|
35
35
|
realSession,
|
|
36
|
-
projectPath
|
|
37
|
-
pendingSession: pendingSession || null,
|
|
36
|
+
projectPath
|
|
38
37
|
})
|
|
39
38
|
});
|
|
40
39
|
return response.ok;
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ekkos/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.35",
|
|
4
4
|
"description": "Setup ekkOS memory for AI coding assistants (Claude Code, Cursor, Windsurf)",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"ekkos": "dist/index.js",
|
|
8
8
|
"cli": "dist/index.js",
|
|
9
|
-
"ekkos-capture": "dist/cache/capture.js"
|
|
9
|
+
"ekkos-capture": "dist/cache/capture.js",
|
|
10
|
+
"ekkos-promote": "dist/cron/promoter.js"
|
|
10
11
|
},
|
|
11
12
|
"scripts": {
|
|
12
13
|
"build": "tsc",
|
|
@@ -28,6 +29,7 @@
|
|
|
28
29
|
"author": "ekkOS",
|
|
29
30
|
"license": "MIT",
|
|
30
31
|
"dependencies": {
|
|
32
|
+
"@ekkos/prometheus": "*",
|
|
31
33
|
"@supabase/supabase-js": "^2.39.8",
|
|
32
34
|
"blessed": "^0.1.81",
|
|
33
35
|
"blessed-contrib": "^4.11.0",
|
package/templates/CLAUDE.md
CHANGED
|
@@ -53,28 +53,6 @@ After `/clear`, when you see restored turns in `<system-reminder>` (pattern: `**
|
|
|
53
53
|
```
|
|
54
54
|
This is the ONLY way users see that restoration worked. Hook output is invisible to them.
|
|
55
55
|
|
|
56
|
-
### RULE 6: AUTO-RESTORE AFTER COMPACTION (CONTEXT GUARDIAN)
|
|
57
|
-
When you see `<ekkos-context-preserved>` in the conversation (appears after auto-compaction):
|
|
58
|
-
1. **IMMEDIATELY** call `ekkOS_RestoreContext` with the `restoration_token` from the tag
|
|
59
|
-
2. This restores your working memory that was preserved before compaction
|
|
60
|
-
3. Start your response with:
|
|
61
|
-
```
|
|
62
|
-
✓ **Context restored** - ekkOS preserved X turns before compaction
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
**This is how seamless context continuity works:**
|
|
66
|
-
- PreCompact hook fires → ekkOS_PreserveContext saves your state
|
|
67
|
-
- Claude Code compacts → Summary includes the preservation tag
|
|
68
|
-
- You see the tag → Call ekkOS_RestoreContext → Full context restored
|
|
69
|
-
- User experiences zero knowledge loss despite compaction
|
|
70
|
-
|
|
71
|
-
**Example restoration call:**
|
|
72
|
-
```
|
|
73
|
-
ekkOS_RestoreContext({
|
|
74
|
-
restoration_token: "<token from tag>"
|
|
75
|
-
})
|
|
76
|
-
```
|
|
77
|
-
|
|
78
56
|
---
|
|
79
57
|
|
|
80
58
|
## SKILL TRIGGERS (MANDATORY)
|
|
@@ -101,7 +79,8 @@ Call skills using `Skill(skill: "name")` when you detect these triggers:
|
|
|
101
79
|
| Trigger Keywords | Agent | When to Use |
|
|
102
80
|
|------------------|-------|-------------|
|
|
103
81
|
| extension, vsix, publish, marketplace, ekkos-connect | `extension-manager` | Version bumps, VSIX builds, publishing |
|
|
104
|
-
| vercel, deploy
|
|
82
|
+
| vercel, deploy to vercel, platform.ekkos.dev, apps/web | `devops` | Vercel deployments (link + archive mode) |
|
|
83
|
+
| deploy, railway, workers, pm2, restart, logs, queue | `railway-manager` | Railway deployments, service management |
|
|
105
84
|
| commit, push, branch, merge, git, pull request, rebase | `git-companion` | All git operations |
|
|
106
85
|
| error, bug, broken, not working, failing, crash | `debug-detective` | Systematic debugging |
|
|
107
86
|
| review, PR, check this code, code quality | `code-reviewer` | Code reviews |
|
|
@@ -110,25 +89,6 @@ Call skills using `Skill(skill: "name")` when you detect these triggers:
|
|
|
110
89
|
| backend, API, database, Supabase, RLS | `backend` | API and database work |
|
|
111
90
|
| test, QA, quality, coverage | `qa` | Testing and quality assurance |
|
|
112
91
|
| plan, architect, design, implement feature | `tech-lead` | Complex planning and coordination |
|
|
113
|
-
| research, papers, arXiv, cutting edge, latest AI | `research-scout` | Monitor AI research, update roadmap |
|
|
114
|
-
|
|
115
|
-
**Vercel Project Mapping** (apps/ folder → Vercel project → URL):
|
|
116
|
-
|
|
117
|
-
| apps/ folder | Vercel project | Production URL |
|
|
118
|
-
|-------------|----------------|----------------|
|
|
119
|
-
| `apps/web` | **platform** | platform.ekkos.dev |
|
|
120
|
-
| `apps/memory` | memory | api.ekkos.dev |
|
|
121
|
-
| `apps/proxy` | proxy | proxy.ekkos.dev |
|
|
122
|
-
| `apps/docs` | docs | docs.ekkos.dev |
|
|
123
|
-
| `apps/marketing` | marketing | ekkos.dev |
|
|
124
|
-
| `apps/ekkosca` | ekkosca | ekkos.ca |
|
|
125
|
-
| `apps/blog` | blog | blog.ekkos.dev |
|
|
126
|
-
| `apps/support` | support | support.ekkos.dev |
|
|
127
|
-
| `apps/labs` | labs | ekkoslabs.com |
|
|
128
|
-
| `apps/admin` | admin | admin.ekkos.ca |
|
|
129
|
-
| `apps/sdk` | sdk | sdk-ekkos.vercel.app |
|
|
130
|
-
|
|
131
|
-
**NOTE:** `apps/web` → Vercel project name is `platform`, NOT `web`.
|
|
132
92
|
|
|
133
93
|
**How it works:**
|
|
134
94
|
1. Detect trigger keywords in user request
|
|
@@ -149,55 +109,39 @@ You: Task(subagent_type="extension-manager", prompt="Bump version...")
|
|
|
149
109
|
|
|
150
110
|
---
|
|
151
111
|
|
|
152
|
-
## MCP Tools (
|
|
112
|
+
## MCP Tools (31 Total)
|
|
153
113
|
|
|
154
|
-
### Core Memory Tools
|
|
114
|
+
### Core Memory Tools
|
|
155
115
|
| Tool | Description |
|
|
156
116
|
|------|-------------|
|
|
157
117
|
| `ekkOS_Search` | 🔴 REQUIRED: Search all 11 layers before answering |
|
|
158
|
-
| `
|
|
118
|
+
| `ekkOS_Context` | Get relevant context for a task |
|
|
159
119
|
| `ekkOS_Capture` | Capture memory events |
|
|
160
120
|
| `ekkOS_Forge` | 🔴 REQUIRED: Create pattern from solution |
|
|
161
|
-
| `
|
|
121
|
+
| `ekkOS_Directive` | 🔴 REQUIRED: Create MUST/NEVER/PREFER/AVOID rules |
|
|
162
122
|
| `ekkOS_Outcome` | Track if pattern worked or failed |
|
|
163
|
-
| `
|
|
164
|
-
|
|
165
|
-
### Context & Retrieval Tools (5)
|
|
166
|
-
| Tool | Description |
|
|
167
|
-
|------|-------------|
|
|
168
|
-
| `ekkOS_Context` | Get relevant context for a task |
|
|
169
|
-
| `ekkOS_Codebase` | Search project code embeddings |
|
|
170
|
-
| `ekkOS_Recall` | Recall past conversations by time |
|
|
171
|
-
| `ekkOS_PreserveContext` | 🔴 REQUIRED: Preserve working memory before compaction |
|
|
172
|
-
| `ekkOS_RestoreContext` | 🔴 REQUIRED: Restore context after compaction (RULE 6) |
|
|
173
|
-
|
|
174
|
-
### Utility Tools (8)
|
|
175
|
-
| Tool | Description |
|
|
176
|
-
|------|-------------|
|
|
123
|
+
| `ekkOS_Detect` | 🔴 REQUIRED: Auto-detect which patterns were used |
|
|
177
124
|
| `ekkOS_Summary` | 🔴 REQUIRED: Get summary of MCP activity |
|
|
178
125
|
| `ekkOS_Conflict` | 🔴 REQUIRED: Check for conflicts before destructive actions |
|
|
126
|
+
| `ekkOS_Recall` | Recall past conversations by time |
|
|
127
|
+
| `ekkOS_Codebase` | Search project code embeddings |
|
|
128
|
+
| `ekkOS_Stats` | Get statistics for all layers |
|
|
129
|
+
| `ekkOS_Track` | Track when pattern is applied |
|
|
179
130
|
| `ekkOS_Reflect` | Analyze response for improvement opportunities |
|
|
180
|
-
| `ekkOS_Detect` | 🔴 REQUIRED: Auto-detect which patterns were used |
|
|
181
|
-
| `ekkOS_Export` | Export your patterns, directives, plans as portable JSON backup |
|
|
182
|
-
| `ekkOS_Import` | Import memory from backup (auto-deduplication) |
|
|
183
|
-
| `ekkOS_Why` | Explain why a pattern or decision was made |
|
|
184
|
-
| `ekkOS_Health` | System health check for ekkOS infrastructure |
|
|
185
131
|
|
|
186
|
-
###
|
|
132
|
+
### Schema Awareness Tools
|
|
187
133
|
| Tool | Description |
|
|
188
134
|
|------|-------------|
|
|
189
|
-
| `
|
|
190
|
-
| `
|
|
191
|
-
| `ekkOS_DeleteDirective` | Remove a directive |
|
|
192
|
-
| `ekkOS_UniversalDirectives` | Get directives that apply to all users (constitutional) |
|
|
135
|
+
| `ekkOS_IndexSchema` | Index database schemas (Supabase, Prisma, TypeScript) |
|
|
136
|
+
| `ekkOS_GetSchema` | Get schema for a specific table/type |
|
|
193
137
|
|
|
194
|
-
###
|
|
138
|
+
### Portability Tools
|
|
195
139
|
| Tool | Description |
|
|
196
140
|
|------|-------------|
|
|
197
|
-
| `
|
|
198
|
-
| `
|
|
141
|
+
| `ekkOS_Export` | Export your patterns, directives, plans as portable JSON backup |
|
|
142
|
+
| `ekkOS_Import` | Import memory from backup (auto-deduplication) |
|
|
199
143
|
|
|
200
|
-
### Plan Management
|
|
144
|
+
### Plan Management
|
|
201
145
|
| Tool | Description |
|
|
202
146
|
|------|-------------|
|
|
203
147
|
| `ekkOS_Plan` | Create structured task plan |
|
|
@@ -209,7 +153,7 @@ You: Task(subagent_type="extension-manager", prompt="Bump version...")
|
|
|
209
153
|
| `ekkOS_Templates` | List available templates |
|
|
210
154
|
| `ekkOS_FromTemplate` | Create plan from template |
|
|
211
155
|
|
|
212
|
-
### Secrets Management (
|
|
156
|
+
### Secrets Management (Layer 11)
|
|
213
157
|
| Tool | Description |
|
|
214
158
|
|------|-------------|
|
|
215
159
|
| `ekkOS_StoreSecret` | Encrypt and store sensitive data (AES-256-GCM) |
|
|
@@ -218,39 +162,6 @@ You: Task(subagent_type="extension-manager", prompt="Bump version...")
|
|
|
218
162
|
| `ekkOS_DeleteSecret` | Permanently delete a secret |
|
|
219
163
|
| `ekkOS_RotateSecret` | Update secret with new value |
|
|
220
164
|
|
|
221
|
-
### Project/Sync Tools (4)
|
|
222
|
-
| Tool | Description |
|
|
223
|
-
|------|-------------|
|
|
224
|
-
| `ekkOS_ProjectInit` | Initialize ekkOS for a new project |
|
|
225
|
-
| `ekkOS_Ingest` | Bulk ingest data into memory layers |
|
|
226
|
-
| `ekkOS_Snapshot` | Create point-in-time snapshot of memory state |
|
|
227
|
-
| `ekkOS_Sync` | Sync local and cloud memory state |
|
|
228
|
-
|
|
229
|
-
### Session Management (1)
|
|
230
|
-
| Tool | Description |
|
|
231
|
-
|------|-------------|
|
|
232
|
-
| `ekkOS_Session` | Manage L1 Working Memory sessions (start/resume/end) |
|
|
233
|
-
|
|
234
|
-
### Learning Tools (2)
|
|
235
|
-
| Tool | Description |
|
|
236
|
-
|------|-------------|
|
|
237
|
-
| `ekkOS_Learn` | Auto-learning from corrections, successes, observations |
|
|
238
|
-
| `ekkOS_ReviewLearning` | Review pending learning candidates, approve/reject patterns |
|
|
239
|
-
|
|
240
|
-
### Relationship Tools (2)
|
|
241
|
-
| Tool | Description |
|
|
242
|
-
|------|-------------|
|
|
243
|
-
| `ekkOS_Link` | Create relationships between patterns |
|
|
244
|
-
| `ekkOS_Playbook` | Manage ordered sequences of patterns (workflows) |
|
|
245
|
-
|
|
246
|
-
### PROMETHEUS Tools (4)
|
|
247
|
-
| Tool | Description |
|
|
248
|
-
|------|-------------|
|
|
249
|
-
| `ekkOS_Delta` | Compute improvement score using Δ_prometheus formula |
|
|
250
|
-
| `ekkOS_MetaState` | System introspection ("I know what I know") |
|
|
251
|
-
| `ekkOS_Goal` | Manage persistent objectives and success criteria |
|
|
252
|
-
| `ekkOS_Strategy` | Context-aware strategy selection for tasks |
|
|
253
|
-
|
|
254
165
|
---
|
|
255
166
|
|
|
256
167
|
## Proactive Tool Triggers (MEMORIZE THESE)
|
|
@@ -293,28 +204,6 @@ You: Task(subagent_type="extension-manager", prompt="Bump version...")
|
|
|
293
204
|
- Need to retrieve stored credentials
|
|
294
205
|
- User asks "do you have my X key?"
|
|
295
206
|
|
|
296
|
-
### Always Use Context Preservation When:
|
|
297
|
-
- PreCompact hook fires (auto-triggered)
|
|
298
|
-
- See `<ekkos-context-preserved>` tag (auto-restore)
|
|
299
|
-
- RULE 6 activation
|
|
300
|
-
|
|
301
|
-
### Always Use Learning Tools When:
|
|
302
|
-
- User corrects you (ekkOS_Learn mode: correction)
|
|
303
|
-
- Solution succeeds (ekkOS_Learn mode: success)
|
|
304
|
-
- Discover insight (ekkOS_Learn mode: observe)
|
|
305
|
-
- Review pending patterns (ekkOS_ReviewLearning)
|
|
306
|
-
|
|
307
|
-
### Always Use Relationship Tools When:
|
|
308
|
-
- Patterns are sequential (ekkOS_Link type: leads_to)
|
|
309
|
-
- Creating workflows (ekkOS_Playbook)
|
|
310
|
-
- Patterns are alternatives (ekkOS_Link type: alternative)
|
|
311
|
-
|
|
312
|
-
### Always Use PROMETHEUS Tools When:
|
|
313
|
-
- Evaluating system improvement (ekkOS_Delta)
|
|
314
|
-
- Self-assessment needed (ekkOS_MetaState)
|
|
315
|
-
- Setting objectives (ekkOS_Goal)
|
|
316
|
-
- Choosing approach (ekkOS_Strategy)
|
|
317
|
-
|
|
318
207
|
---
|
|
319
208
|
|
|
320
209
|
## 11-Layer Memory Architecture
|
|
@@ -364,21 +253,20 @@ Call `ekkOS_Directive` when user says:
|
|
|
364
253
|
**EVERY response MUST end with this footer:**
|
|
365
254
|
```
|
|
366
255
|
---
|
|
367
|
-
{IDE} ({Model}) · 🧠 **ekkOS_™** · Turn {N} ·
|
|
256
|
+
{IDE} ({Model}) · 🧠 **ekkOS_™** · Turn {N} · 📅 {Timestamp}
|
|
368
257
|
```
|
|
369
258
|
|
|
370
259
|
**How to detect values:**
|
|
371
260
|
- **IDE**: Claude Code, Cursor, Windsurf, etc. (from environment)
|
|
372
261
|
- **Model**: Sonnet 4.5, Opus 4.5, etc. (from your model name)
|
|
373
262
|
- **Turn Number**: From hook header (e.g., "Turn 47") - starts at 0 for each new session
|
|
374
|
-
- **Session Name**: From hook header (e.g., "sol-gem-dig") - human-readable session identifier
|
|
375
263
|
- **Timestamp**: From hook header (accurate local time in EST)
|
|
376
264
|
|
|
377
265
|
**Examples:**
|
|
378
|
-
- `Claude Code (Sonnet 4.5) · 🧠 **ekkOS_™** · Turn 12 ·
|
|
379
|
-
- `Cursor (Claude Sonnet 4) · 🧠 **ekkOS_™** · Turn 5 ·
|
|
266
|
+
- `Claude Code (Sonnet 4.5) · 🧠 **ekkOS_™** · Turn 12 · 📅 2026-01-09 4:50 PM EST`
|
|
267
|
+
- `Cursor (Claude Sonnet 4) · 🧠 **ekkOS_™** · Turn 5 · 📅 2026-01-09 10:15 AM EST`
|
|
380
268
|
|
|
381
|
-
**The hook header shows:** `🧠 ekkOS Memory | Turn {N} |
|
|
269
|
+
**The hook header shows:** `🧠 ekkOS Memory | Turn {N} | Session: {ID} | {timestamp}`
|
|
382
270
|
|
|
383
271
|
---
|
|
384
272
|
|