@ekkos/cli 1.0.34 → 1.0.36
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 +1 -1
- 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/hooks/assistant-response.ps1 +26 -94
- package/templates/hooks/lib/count-tokens.cjs +0 -0
- package/templates/hooks/lib/ekkos-reminders.sh +0 -0
- package/templates/hooks/session-start.ps1 +224 -61
- package/templates/hooks/session-start.sh +1 -1
- package/templates/hooks/stop.ps1 +249 -103
- package/templates/hooks/stop.sh +1 -1
- package/templates/hooks/user-prompt-submit.ps1 +519 -129
- package/templates/hooks/user-prompt-submit.sh +2 -2
- 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/install.sh +0 -0
- package/templates/windsurf-hooks/lib/contract.sh +0 -0
- 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
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# ekkOS Agents
|
|
2
|
+
|
|
3
|
+
Automatic agents that enhance your Claude Code experience with persistent memory and context preservation.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
These agents are automatically installed when you set up ekkos-connect:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# During ekkos-connect installation, agents are copied to:
|
|
11
|
+
~/.claude/agents/
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Available Agents
|
|
15
|
+
|
|
16
|
+
### Context Guardian (`context-guardian.json`)
|
|
17
|
+
|
|
18
|
+
**Version:** 3.0.0
|
|
19
|
+
**Solves:** The "95% of issues from compacting" problem in Claude Code
|
|
20
|
+
|
|
21
|
+
**What it does:**
|
|
22
|
+
- Automatically preserves your working memory before Claude Code compaction
|
|
23
|
+
- Seamlessly restores context when you resume (mid-session or new session)
|
|
24
|
+
- Prevents infinite compaction loops with circuit breaker
|
|
25
|
+
- Preserves file read cache to eliminate redundant reads
|
|
26
|
+
- Auto-refreshes directives and CLAUDE.md after restoration
|
|
27
|
+
- Zero user action required - it just works
|
|
28
|
+
|
|
29
|
+
**How it works:**
|
|
30
|
+
|
|
31
|
+
| Trigger | What Happens |
|
|
32
|
+
|---------|--------------|
|
|
33
|
+
| **Pre-Compaction (85-90%)** | Detects token limit → captures state → promotes to ekkOS episodic memory |
|
|
34
|
+
| **Mid-Session (NEW v2.0)** | Checks every interaction → detects compaction → auto-restores silently |
|
|
35
|
+
| **Post-Compaction (NEW v3.0)** | Refreshes directives → injects file cache → user never notices gap |
|
|
36
|
+
| **Session Start** | Checks for snapshot → restores context → injects into conversation |
|
|
37
|
+
|
|
38
|
+
**v3.0 Enhancements (GitHub-Driven):**
|
|
39
|
+
|
|
40
|
+
| Issue | Problem | Solution |
|
|
41
|
+
|-------|---------|----------|
|
|
42
|
+
| #6541, #2222, #2283 | Infinite compaction loops | Circuit breaker with exponential backoff |
|
|
43
|
+
| #11487 | Files re-read 10-15x after compact | File read cache preservation |
|
|
44
|
+
| #3021 | Rules/memory forgotten | Auto-refresh directives + CLAUDE.md |
|
|
45
|
+
| #3274 | Compact blocks normal use | Async preservation at 85% threshold |
|
|
46
|
+
| #5720 | No warning before compact | Optional pre-compaction notification |
|
|
47
|
+
|
|
48
|
+
**Setup:**
|
|
49
|
+
|
|
50
|
+
Add to your shell profile (`.zshrc`, `.bashrc`):
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# Core Configuration
|
|
54
|
+
export EKKOS_API_URL="https://api.ekkos.dev"
|
|
55
|
+
export EKKOS_API_KEY="ekk_your_key_here"
|
|
56
|
+
export EKKOS_USER_ID="your_user_id"
|
|
57
|
+
export CONTEXT_GUARDIAN_ENABLED="true"
|
|
58
|
+
export CONTEXT_GUARDIAN_AUTO_PRESERVE="true"
|
|
59
|
+
export CONTEXT_GUARDIAN_TOKEN_THRESHOLD="0.90"
|
|
60
|
+
|
|
61
|
+
# Mid-Session Restoration (v2.0)
|
|
62
|
+
export CONTEXT_GUARDIAN_AUTO_RESTORE="true"
|
|
63
|
+
export CONTEXT_GUARDIAN_RESTORATION_WINDOW="300"
|
|
64
|
+
export CONTEXT_GUARDIAN_SILENT_RESTORE="true"
|
|
65
|
+
|
|
66
|
+
# Loop Prevention (v3.0)
|
|
67
|
+
export CONTEXT_GUARDIAN_MAX_COMPACTIONS="5"
|
|
68
|
+
export CONTEXT_GUARDIAN_COOLDOWN_MS="60000"
|
|
69
|
+
|
|
70
|
+
# Directives Refresh (v3.0)
|
|
71
|
+
export CONTEXT_GUARDIAN_REFRESH_DIRECTIVES="true"
|
|
72
|
+
export CONTEXT_GUARDIAN_REREAD_CLAUDE_MD="true"
|
|
73
|
+
|
|
74
|
+
# File Cache (v3.0)
|
|
75
|
+
export CONTEXT_GUARDIAN_PRESERVE_FILE_CACHE="true"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**Get your credentials:**
|
|
79
|
+
```bash
|
|
80
|
+
# Get API key and user ID
|
|
81
|
+
curl https://api.ekkos.dev/api/v1/me \
|
|
82
|
+
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Or visit: https://platform.ekkos.dev/settings/api-keys
|
|
86
|
+
|
|
87
|
+
**Manual commands:**
|
|
88
|
+
- `/preserve` - Manually trigger context preservation
|
|
89
|
+
- `/restore` - Manually trigger context restoration
|
|
90
|
+
- `/snapshot-status` - Check if snapshot exists for current session
|
|
91
|
+
- `/clear-snapshot` - Clear local restoration token
|
|
92
|
+
- `/circuit-status` - Show circuit breaker state (v3.0)
|
|
93
|
+
|
|
94
|
+
**Documentation:** See `context-guardian-guide.md` for complete details.
|
|
95
|
+
|
|
96
|
+
### GitHub Test Agent (`github-test-agent.md`)
|
|
97
|
+
|
|
98
|
+
**Version:** 1.0.0
|
|
99
|
+
**Solves:** Manual test-fix-push cycles when CI fails
|
|
100
|
+
|
|
101
|
+
**What it does:**
|
|
102
|
+
- Runs GitHub Actions test workflows via `gh` CLI
|
|
103
|
+
- Monitors for completion and parses failure logs
|
|
104
|
+
- Automatically diagnoses and fixes test failures
|
|
105
|
+
- Commits, pushes, and re-runs until green
|
|
106
|
+
- Learns from fixes via ekkOS pattern forging
|
|
107
|
+
|
|
108
|
+
**Self-healing loop:**
|
|
109
|
+
```
|
|
110
|
+
TRIGGER → POLL → PARSE → FIX → VERIFY → PUSH → LOOP
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**Safety rails:**
|
|
114
|
+
- Max 5 fix attempts per session
|
|
115
|
+
- Max 3 attempts for same error
|
|
116
|
+
- Requires approval for architectural changes
|
|
117
|
+
- Local verification before pushing
|
|
118
|
+
- Memory-first debugging (searches patterns before fixing)
|
|
119
|
+
|
|
120
|
+
**Trigger words:** test, CI, workflow, github actions, run tests, fix tests, green build
|
|
121
|
+
|
|
122
|
+
**Example:**
|
|
123
|
+
```
|
|
124
|
+
User: "Run the extension tests and fix any failures"
|
|
125
|
+
Agent: Triggers workflow → parses failures → fixes code → pushes → loops until green
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## How Agents Work
|
|
131
|
+
|
|
132
|
+
Agents run automatically in Claude Code when specific conditions are met:
|
|
133
|
+
|
|
134
|
+
- **Context Guardian:** Runs when token count exceeds threshold, on every user interaction (mid-session check), or on session start
|
|
135
|
+
- Future agents will add more capabilities (pattern suggestions, code review, etc.)
|
|
136
|
+
|
|
137
|
+
## Technical Details
|
|
138
|
+
|
|
139
|
+
- Agents are JSON configuration files that define:
|
|
140
|
+
- Name and description
|
|
141
|
+
- System prompt (instructions)
|
|
142
|
+
- Available tools (MCP tools they can call)
|
|
143
|
+
- Model to use (sonnet, opus, haiku)
|
|
144
|
+
- Allowed commands (for security)
|
|
145
|
+
|
|
146
|
+
- Agents run with access to your conversation context
|
|
147
|
+
- They can call ekkOS MCP tools to preserve/restore memory
|
|
148
|
+
- They operate silently in the background
|
|
149
|
+
|
|
150
|
+
## Impact
|
|
151
|
+
|
|
152
|
+
**Context Guardian v3.0 metrics:**
|
|
153
|
+
|
|
154
|
+
| Metric | Before | After v3.0 |
|
|
155
|
+
|--------|--------|------------|
|
|
156
|
+
| Context loss rate | 95% | <1% |
|
|
157
|
+
| Infinite loop incidents | Common | 0% |
|
|
158
|
+
| Redundant file reads | 10-15x | <2x |
|
|
159
|
+
| Directives forgotten | 100% | 0% |
|
|
160
|
+
| Preservation time | 2-5s blocking | <500ms async |
|
|
161
|
+
| Productivity saved | $0 | 50+ hours/dev/year |
|
|
162
|
+
| ROI | N/A | $7.5K/dev/year |
|
|
163
|
+
|
|
164
|
+
## Version History
|
|
165
|
+
|
|
166
|
+
| Version | Features |
|
|
167
|
+
|---------|----------|
|
|
168
|
+
| v1.0 | Cross-session restoration, local fallback |
|
|
169
|
+
| v2.0 | Mid-session restoration, check-on-every-interaction |
|
|
170
|
+
| v3.0 | Circuit breaker, file cache, directives refresh, async preservation |
|
|
171
|
+
|
|
172
|
+
## Support
|
|
173
|
+
|
|
174
|
+
- **Issues:** https://github.com/ekkos/ekkos/issues
|
|
175
|
+
- **Docs:** https://docs.ekkos.dev/agents
|
|
176
|
+
- **Email:** support@ekkos.dev
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
**Built with ❤️ by ekkOS™**
|
|
181
|
+
|
|
182
|
+
Context Guardian v3.0: Making compaction invisible, one interaction at a time.
|