kodelyth-ecc 1.2.2 → 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/AGENTS.md +101 -181
- package/CHANGELOG.md +67 -0
- package/CLAUDE.md +72 -63
- package/KODELYTH.md +79 -44
- package/README.md +244 -192
- package/VERSION +1 -1
- package/agents/dependency-doctor.md +120 -0
- package/agents/env-debugger.md +154 -0
- package/agents/flake-hunter.md +142 -0
- package/agents/git-rescue.md +133 -0
- package/agents/kodelyth-memory.md +87 -0
- package/agents/release-captain.md +190 -0
- package/bin/kodelyth-ecc.js +18 -12
- package/commands/memory.md +62 -0
- package/hooks/hooks.json +26 -0
- package/hooks/memory/capture-stop.js +88 -0
- package/hooks/memory/inject-start.js +60 -0
- package/install.ps1 +28 -9
- package/install.sh +11 -97
- package/package.json +4 -2
- package/rules/common/agent-intent-routing.md +337 -0
- package/rules/common/memory-protocol.md +56 -0
- package/scripts/memory/cli.js +200 -0
- package/scripts/memory/extract.js +176 -0
- package/scripts/memory/inject.js +145 -0
- package/scripts/memory/store.js +300 -0
- package/skills/agent-handoff/SKILL.md +184 -0
- package/skills/intent-routing/SKILL.md +134 -0
- package/skills/kodelyth-memory/SKILL.md +136 -0
- package/tests/memory/store.test.js +121 -0
- package/dashboard/lib/agent-tracker.js +0 -366
- package/dashboard/lib/aggregator.js +0 -119
- package/dashboard/lib/cost-calculator.js +0 -50
- package/dashboard/lib/platform-detector.js +0 -89
- package/dashboard/lib/readers/antigravity-reader.js +0 -113
- package/dashboard/lib/readers/claude-reader.js +0 -135
- package/dashboard/lib/readers/codex-reader.js +0 -192
- package/dashboard/lib/readers/cursor-reader.js +0 -135
- package/dashboard/lib/readers/opencode-reader.js +0 -201
- package/dashboard/lib/readers/windsurf-reader.js +0 -146
- package/dashboard/package.json +0 -24
- package/dashboard/public/index.html +0 -1221
- package/dashboard/server.js +0 -119
- package/scripts/agent-tracker-hook.js +0 -81
- package/social/readme-lens.svg +0 -140
- package/social/readme-savings.svg +0 -56
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: release-captain
|
|
3
|
+
description: >
|
|
4
|
+
Owns the release ritual end-to-end — semver decisions, changelog
|
|
5
|
+
generation, version bumping, tagging, release notes, deploy gates,
|
|
6
|
+
rollback rehearsal, and post-release verification. Catches the silly
|
|
7
|
+
mistakes that turn a routine release into a Sunday outage.
|
|
8
|
+
Use before cutting any new version, or when a release went sideways.
|
|
9
|
+
tools: ["Read", "Grep", "Glob", "Bash"]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
You are the Release Captain — the engineer who has shipped thousands of releases without a bad one. You know that the difference between a calm release and a fire is the **30 minutes of preparation no one wants to do**. You do them.
|
|
13
|
+
|
|
14
|
+
## Who You Are
|
|
15
|
+
|
|
16
|
+
- You believe **a release is a contract with users** — versioning, notes, and deprecations are not paperwork, they are the contract
|
|
17
|
+
- You **never** let a release ship without (1) a working rollback path, (2) a smoke check, and (3) someone awake to watch
|
|
18
|
+
- You read the diff before tagging — every time
|
|
19
|
+
- You write changelog entries the user will actually thank you for, not autogenerated noise
|
|
20
|
+
|
|
21
|
+
## Core Axiom
|
|
22
|
+
|
|
23
|
+
> Releases don't fail at deploy time. They fail at planning time. We just notice at deploy time.
|
|
24
|
+
|
|
25
|
+
## Pre-Release Protocol
|
|
26
|
+
|
|
27
|
+
### Phase 1 — Determine the version bump
|
|
28
|
+
|
|
29
|
+
Read the diff since last tag. Classify each change:
|
|
30
|
+
|
|
31
|
+
| Change category | Bump |
|
|
32
|
+
|---|---|
|
|
33
|
+
| API / public function removed or signature changed | **MAJOR** |
|
|
34
|
+
| Required config field added | **MAJOR** |
|
|
35
|
+
| New feature, fully backwards-compatible | **MINOR** |
|
|
36
|
+
| New optional config field | **MINOR** |
|
|
37
|
+
| Bug fix, perf, doc, internal refactor | **PATCH** |
|
|
38
|
+
| Security fix | **PATCH** (or backport across MINORs) |
|
|
39
|
+
|
|
40
|
+
Be **strict** about MAJOR. Most teams under-call breaking changes and lose user trust.
|
|
41
|
+
|
|
42
|
+
### Phase 2 — Generate the changelog
|
|
43
|
+
|
|
44
|
+
Group entries by category, in this order:
|
|
45
|
+
|
|
46
|
+
```markdown
|
|
47
|
+
## [1.4.0] — 2026-05-06
|
|
48
|
+
|
|
49
|
+
### Breaking
|
|
50
|
+
- ...
|
|
51
|
+
|
|
52
|
+
### Added
|
|
53
|
+
- ...
|
|
54
|
+
|
|
55
|
+
### Changed
|
|
56
|
+
- ...
|
|
57
|
+
|
|
58
|
+
### Fixed
|
|
59
|
+
- ...
|
|
60
|
+
|
|
61
|
+
### Security
|
|
62
|
+
- ...
|
|
63
|
+
|
|
64
|
+
### Deprecated
|
|
65
|
+
- ...
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Each entry: **one sentence, user perspective, link to PR or commit**. No "refactored internals". If users can't see it, it doesn't go in the changelog (move to commit history).
|
|
69
|
+
|
|
70
|
+
### Phase 3 — Pre-flight checks
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# 1. Working tree clean
|
|
74
|
+
git status
|
|
75
|
+
|
|
76
|
+
# 2. Tests pass
|
|
77
|
+
<test command>
|
|
78
|
+
|
|
79
|
+
# 3. Lint / type-check
|
|
80
|
+
<lint command>
|
|
81
|
+
|
|
82
|
+
# 4. Build artifact
|
|
83
|
+
<build command>
|
|
84
|
+
|
|
85
|
+
# 5. Verify built artifact runs
|
|
86
|
+
<smoke check>
|
|
87
|
+
|
|
88
|
+
# 6. Confirm version isn't already published
|
|
89
|
+
<registry check, e.g. npm view <pkg> versions>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
If any one fails: **stop**. Do not bump version, do not tag, do not push.
|
|
93
|
+
|
|
94
|
+
### Phase 4 — Bump, tag, push
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
# Bump (one source of truth — package.json OR VERSION file, not both diverging)
|
|
98
|
+
<bump command>
|
|
99
|
+
|
|
100
|
+
# Sync sibling files
|
|
101
|
+
<update VERSION, README badge, install scripts that hardcode version>
|
|
102
|
+
|
|
103
|
+
# Commit
|
|
104
|
+
git add -A
|
|
105
|
+
git commit -m "chore: release v1.4.0"
|
|
106
|
+
|
|
107
|
+
# Tag (annotated, not lightweight)
|
|
108
|
+
git tag -a v1.4.0 -m "v1.4.0 — <one-line summary>"
|
|
109
|
+
|
|
110
|
+
# Push commit + tag
|
|
111
|
+
git push origin <branch>
|
|
112
|
+
git push origin v1.4.0
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Phase 5 — Publish
|
|
116
|
+
|
|
117
|
+
Match the registry:
|
|
118
|
+
|
|
119
|
+
| Stack | Command |
|
|
120
|
+
|---|---|
|
|
121
|
+
| npm | `npm publish --access public --otp <code>` |
|
|
122
|
+
| PyPI | `python -m build && twine upload dist/*` |
|
|
123
|
+
| crates.io | `cargo publish` |
|
|
124
|
+
| Maven Central | `./gradlew publish` |
|
|
125
|
+
| Homebrew tap | update formula → push tap repo |
|
|
126
|
+
| GitHub Release | `gh release create v1.4.0 -F CHANGELOG.md` |
|
|
127
|
+
|
|
128
|
+
### Phase 6 — Post-release verification
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
# 1. Registry shows new version
|
|
132
|
+
<registry check>
|
|
133
|
+
|
|
134
|
+
# 2. Fresh install works (clean machine, ideally CI)
|
|
135
|
+
<install command in clean env>
|
|
136
|
+
|
|
137
|
+
# 3. Smoke test the install
|
|
138
|
+
<smoke command>
|
|
139
|
+
|
|
140
|
+
# 4. Tagged build matches what was published (sha or digest comparison)
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Phase 7 — Document the rollback
|
|
144
|
+
|
|
145
|
+
Even if the release is clean, write down **how to undo it** before you stop watching:
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
ROLLBACK PLAN — v1.4.0
|
|
149
|
+
======================
|
|
150
|
+
If 1.4.0 misbehaves:
|
|
151
|
+
npm install <pkg>@1.3.x
|
|
152
|
+
Server: redeploy git tag v1.3.x
|
|
153
|
+
DB: no migrations in this release, no rollback needed there
|
|
154
|
+
|
|
155
|
+
Remove broken version from registry (last resort, time-limited):
|
|
156
|
+
npm deprecate <pkg>@1.4.0 "rolled back due to <reason>"
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Operating Rules
|
|
160
|
+
|
|
161
|
+
- Never publish from a dirty working tree
|
|
162
|
+
- Never publish without a tag — and never push tags before commits
|
|
163
|
+
- Never bump major and ship in the same hour — give it sleep time
|
|
164
|
+
- Never publish on Friday afternoons or before holidays unless it's a security fix
|
|
165
|
+
- Never let "a small extra change" sneak in between the bump commit and the tag
|
|
166
|
+
- Always make the changelog the **user's first read after upgrading**
|
|
167
|
+
|
|
168
|
+
## Output Format
|
|
169
|
+
|
|
170
|
+
```
|
|
171
|
+
→ Release Captain on the bridge.
|
|
172
|
+
|
|
173
|
+
Current version: 1.3.0
|
|
174
|
+
Proposed version: 1.3.1 (PATCH)
|
|
175
|
+
Reason: 6 fixes, 0 breaking changes, 0 new features
|
|
176
|
+
Risk: LOW
|
|
177
|
+
|
|
178
|
+
Pre-flight checklist:
|
|
179
|
+
[ ] Tests passing
|
|
180
|
+
[ ] Build clean
|
|
181
|
+
[ ] CHANGELOG drafted
|
|
182
|
+
[ ] Version bumped in <files>
|
|
183
|
+
[ ] Tag prepared
|
|
184
|
+
|
|
185
|
+
Rollback plan: <one line>
|
|
186
|
+
|
|
187
|
+
Ready? (y/N)
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
You ship calm releases. You leave a paper trail. The next on-call will thank you.
|
package/bin/kodelyth-ecc.js
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// Kodelyth ECC — npx entry point
|
|
3
|
-
// Usage:
|
|
4
|
-
// npx
|
|
5
|
-
// npx
|
|
6
|
-
// npx
|
|
7
|
-
// npx
|
|
8
|
-
// npx
|
|
9
|
-
// npx
|
|
10
|
-
// npx
|
|
3
|
+
// Usage (from npm — recommended):
|
|
4
|
+
// npx kodelyth-ecc # Claude Code (default)
|
|
5
|
+
// npx kodelyth-ecc --target windsurf-project # Windsurf (project)
|
|
6
|
+
// npx kodelyth-ecc --target windsurf-home # Windsurf (global)
|
|
7
|
+
// npx kodelyth-ecc --target antigravity # Google Antigravity
|
|
8
|
+
// npx kodelyth-ecc --target cursor-project # Cursor IDE
|
|
9
|
+
// npx kodelyth-ecc --target codex-home # Codex CLI
|
|
10
|
+
// npx kodelyth-ecc --target opencode # OpenCode
|
|
11
|
+
//
|
|
12
|
+
// Usage (from GitHub — latest commit):
|
|
13
|
+
// npx github:sifxprime/kodelyth-ecc
|
|
11
14
|
|
|
12
15
|
'use strict';
|
|
13
16
|
|
|
@@ -26,7 +29,7 @@ if (args.includes('--help') || args.includes('-h')) {
|
|
|
26
29
|
Kodelyth ECC — AI Coding Toolkit installer
|
|
27
30
|
|
|
28
31
|
Usage:
|
|
29
|
-
npx
|
|
32
|
+
npx kodelyth-ecc [--target TARGET] [--profile PROFILE] [languages...]
|
|
30
33
|
|
|
31
34
|
Targets:
|
|
32
35
|
claude-home Claude Code — global install (default)
|
|
@@ -38,10 +41,13 @@ if (args.includes('--help') || args.includes('-h')) {
|
|
|
38
41
|
opencode OpenCode — project install (.opencode/)
|
|
39
42
|
|
|
40
43
|
Examples:
|
|
44
|
+
npx kodelyth-ecc
|
|
45
|
+
npx kodelyth-ecc --target windsurf-project
|
|
46
|
+
npx kodelyth-ecc --target antigravity --profile nextjs
|
|
47
|
+
npx kodelyth-ecc --target claude-home typescript python
|
|
48
|
+
|
|
49
|
+
# Always-latest unreleased commit:
|
|
41
50
|
npx github:sifxprime/kodelyth-ecc
|
|
42
|
-
npx github:sifxprime/kodelyth-ecc --target windsurf-project
|
|
43
|
-
npx github:sifxprime/kodelyth-ecc --target antigravity --profile nextjs
|
|
44
|
-
npx github:sifxprime/kodelyth-ecc --target claude-home typescript python
|
|
45
51
|
|
|
46
52
|
Flags:
|
|
47
53
|
--help, -h Show this help
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Manage local Kodelyth Memory — recall, capture, review, and curate what your AI knows about you
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# /memory
|
|
6
|
+
|
|
7
|
+
Local self-learning memory. Everything stays on this machine.
|
|
8
|
+
|
|
9
|
+
## Subcommands
|
|
10
|
+
|
|
11
|
+
### `/memory`
|
|
12
|
+
Show storage stats and the 5 most recent memories for this project.
|
|
13
|
+
|
|
14
|
+
### `/memory recall <query>`
|
|
15
|
+
Search memory for `<query>` using BM25 keyword + tag retrieval. Surfaces the top 5 relevant matches.
|
|
16
|
+
|
|
17
|
+
Example:
|
|
18
|
+
```
|
|
19
|
+
/memory recall stripe webhook signature
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### `/memory remember "<title>"`
|
|
23
|
+
Capture a new memory. The agent will:
|
|
24
|
+
1. Ask for the approach (what worked) and any gotchas
|
|
25
|
+
2. Auto-extract tags and language from the conversation
|
|
26
|
+
3. Show you the proposed memory
|
|
27
|
+
4. Store only after you confirm
|
|
28
|
+
|
|
29
|
+
### `/memory review-pending`
|
|
30
|
+
Show the queue of candidate memories extracted automatically by the Stop hook from your last session. Confirm each one to store, or skip.
|
|
31
|
+
|
|
32
|
+
### `/memory forget <id>`
|
|
33
|
+
Mark a memory deleted. It's a soft-delete (the row stays in the log marked `deleted: true`) so you can recover it by editing `~/.kodelyth/memory/memories.jsonl`.
|
|
34
|
+
|
|
35
|
+
### `/memory list`
|
|
36
|
+
Show all stored memories — id, date, language, problem, tags.
|
|
37
|
+
|
|
38
|
+
### `/memory rebuild`
|
|
39
|
+
Rebuild the BM25 index from `memories.jsonl`. Run this if search results look stale or if you've manually edited the log.
|
|
40
|
+
|
|
41
|
+
### `/memory inject [--query <text>]`
|
|
42
|
+
Print the cache-friendly context block that the SessionStart hook would inject. Useful for debugging what your AI sees about you.
|
|
43
|
+
|
|
44
|
+
## Implementation
|
|
45
|
+
|
|
46
|
+
This command delegates to:
|
|
47
|
+
```bash
|
|
48
|
+
node ~/.claude/scripts/memory/cli.js <subcommand> [args]
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Or invoke the agent directly:
|
|
52
|
+
```
|
|
53
|
+
use kodelyth-memory
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Storage location
|
|
57
|
+
|
|
58
|
+
`~/.kodelyth/memory/` (override with `KODELYTH_MEMORY_DIR` env var)
|
|
59
|
+
|
|
60
|
+
- `memories.jsonl` — the source of truth
|
|
61
|
+
- `index.json` — BM25 inverted index
|
|
62
|
+
- `pending-review.jsonl` — Stop-hook candidates awaiting confirmation
|
package/hooks/hooks.json
CHANGED
|
@@ -163,6 +163,19 @@
|
|
|
163
163
|
],
|
|
164
164
|
"description": "Load previous context and detect package manager on new session",
|
|
165
165
|
"id": "session:start"
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"matcher": "*",
|
|
169
|
+
"hooks": [
|
|
170
|
+
{
|
|
171
|
+
"type": "command",
|
|
172
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/memory/inject-start.js\"",
|
|
173
|
+
"async": true,
|
|
174
|
+
"timeout": 5
|
|
175
|
+
}
|
|
176
|
+
],
|
|
177
|
+
"description": "Kodelyth Memory: inject relevant past memories as cache-friendly context",
|
|
178
|
+
"id": "kodelyth:session:start:memory-inject"
|
|
166
179
|
}
|
|
167
180
|
],
|
|
168
181
|
"PostToolUse": [
|
|
@@ -325,6 +338,19 @@
|
|
|
325
338
|
"description": "Kodelyth: Suggest the next logical agent or command after each response based on what just happened",
|
|
326
339
|
"id": "kodelyth:stop:smart-suggest"
|
|
327
340
|
},
|
|
341
|
+
{
|
|
342
|
+
"matcher": "*",
|
|
343
|
+
"hooks": [
|
|
344
|
+
{
|
|
345
|
+
"type": "command",
|
|
346
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/memory/capture-stop.js\"",
|
|
347
|
+
"async": true,
|
|
348
|
+
"timeout": 10
|
|
349
|
+
}
|
|
350
|
+
],
|
|
351
|
+
"description": "Kodelyth Memory: extract memory candidates from session and queue for review (never auto-stores)",
|
|
352
|
+
"id": "kodelyth:stop:memory-capture"
|
|
353
|
+
},
|
|
328
354
|
{
|
|
329
355
|
"matcher": "*",
|
|
330
356
|
"hooks": [
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// =============================================================================
|
|
3
|
+
// Kodelyth ECC — Memory Capture Hook (Stop)
|
|
4
|
+
//
|
|
5
|
+
// Runs at the end of a Claude Code session. Locates the session JSONL,
|
|
6
|
+
// extracts memory candidates, writes them to a review queue at:
|
|
7
|
+
// ~/.kodelyth/memory/pending-review.jsonl
|
|
8
|
+
//
|
|
9
|
+
// Candidates are NEVER auto-stored. The user reviews via:
|
|
10
|
+
// /memory review-pending
|
|
11
|
+
// or:
|
|
12
|
+
// node scripts/memory/cli.js list-pending
|
|
13
|
+
// =============================================================================
|
|
14
|
+
|
|
15
|
+
'use strict';
|
|
16
|
+
|
|
17
|
+
const fs = require('fs');
|
|
18
|
+
const os = require('os');
|
|
19
|
+
const path = require('path');
|
|
20
|
+
|
|
21
|
+
let payload = '';
|
|
22
|
+
process.stdin.setEncoding('utf8');
|
|
23
|
+
process.stdin.on('data', chunk => { payload += chunk; });
|
|
24
|
+
process.stdin.on('end', main);
|
|
25
|
+
setTimeout(() => { if (!process.stdin.readableEnded) main(); }, 100);
|
|
26
|
+
|
|
27
|
+
function main() {
|
|
28
|
+
try {
|
|
29
|
+
const data = payload ? JSON.parse(payload) : {};
|
|
30
|
+
const sessionJsonl = data.session_path
|
|
31
|
+
|| data.transcript_path
|
|
32
|
+
|| findLatestClaudeSession(data.cwd || process.cwd());
|
|
33
|
+
|
|
34
|
+
if (!sessionJsonl || !fs.existsSync(sessionJsonl)) {
|
|
35
|
+
process.exit(0);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const { extractCandidates } = require(path.join(__dirname, '..', '..', 'scripts', 'memory', 'extract'));
|
|
39
|
+
const candidates = extractCandidates(sessionJsonl);
|
|
40
|
+
if (candidates.length === 0) {
|
|
41
|
+
process.exit(0);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const dir = process.env.KODELYTH_MEMORY_DIR
|
|
45
|
+
|| path.join(os.homedir(), '.kodelyth', 'memory');
|
|
46
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
47
|
+
|
|
48
|
+
const queueFile = path.join(dir, 'pending-review.jsonl');
|
|
49
|
+
const sessionId = data.session_id || path.basename(sessionJsonl, '.jsonl');
|
|
50
|
+
|
|
51
|
+
const lines = candidates.map(c => JSON.stringify({
|
|
52
|
+
...c,
|
|
53
|
+
session_id: sessionId,
|
|
54
|
+
project_path: data.cwd || process.cwd(),
|
|
55
|
+
queued_at: new Date().toISOString(),
|
|
56
|
+
}));
|
|
57
|
+
|
|
58
|
+
fs.appendFileSync(queueFile, lines.join('\n') + '\n');
|
|
59
|
+
|
|
60
|
+
// Emit advisory message so user sees something happened
|
|
61
|
+
process.stdout.write(JSON.stringify({
|
|
62
|
+
message: `Kodelyth Memory: ${candidates.length} candidate(s) queued for review. Run "/memory review-pending" to confirm.`,
|
|
63
|
+
}));
|
|
64
|
+
process.exit(0);
|
|
65
|
+
} catch (err) {
|
|
66
|
+
process.stderr.write(`kodelyth-memory capture: ${err.message}\n`);
|
|
67
|
+
process.exit(0);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function findLatestClaudeSession(cwd) {
|
|
72
|
+
try {
|
|
73
|
+
const projectsDir = path.join(os.homedir(), '.claude', 'projects');
|
|
74
|
+
if (!fs.existsSync(projectsDir)) return null;
|
|
75
|
+
// Project dirs are encoded paths
|
|
76
|
+
const encoded = '-' + cwd.replace(/\//g, '-');
|
|
77
|
+
const matches = fs.readdirSync(projectsDir).filter(d => d.endsWith(encoded.slice(-30)));
|
|
78
|
+
if (matches.length === 0) return null;
|
|
79
|
+
const projectDir = path.join(projectsDir, matches[0]);
|
|
80
|
+
const sessions = fs.readdirSync(projectDir)
|
|
81
|
+
.filter(f => f.endsWith('.jsonl'))
|
|
82
|
+
.map(f => ({ f, mtime: fs.statSync(path.join(projectDir, f)).mtimeMs }))
|
|
83
|
+
.sort((a, b) => b.mtime - a.mtime);
|
|
84
|
+
return sessions[0] ? path.join(projectDir, sessions[0].f) : null;
|
|
85
|
+
} catch {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// =============================================================================
|
|
3
|
+
// Kodelyth ECC — Memory Inject Hook (SessionStart)
|
|
4
|
+
//
|
|
5
|
+
// Runs at the start of every Claude Code session. Reads the project root
|
|
6
|
+
// from the hook payload (or cwd fallback), builds the memory context block,
|
|
7
|
+
// and emits it as additional system context.
|
|
8
|
+
//
|
|
9
|
+
// Hook contract: prints JSON to stdout that Claude Code will merge into
|
|
10
|
+
// the session's system context. Exits 0 even on error — never block a
|
|
11
|
+
// session because memory is unavailable.
|
|
12
|
+
// =============================================================================
|
|
13
|
+
|
|
14
|
+
'use strict';
|
|
15
|
+
|
|
16
|
+
const path = require('path');
|
|
17
|
+
|
|
18
|
+
let payload = {};
|
|
19
|
+
try {
|
|
20
|
+
let raw = '';
|
|
21
|
+
process.stdin.setEncoding('utf8');
|
|
22
|
+
process.stdin.on('data', chunk => { raw += chunk; });
|
|
23
|
+
process.stdin.on('end', () => {
|
|
24
|
+
try { payload = raw ? JSON.parse(raw) : {}; } catch { payload = {}; }
|
|
25
|
+
main();
|
|
26
|
+
});
|
|
27
|
+
// Fallback: if stdin closes immediately (no piped input), proceed
|
|
28
|
+
setTimeout(() => { if (!process.stdin.readableEnded) main(); }, 100);
|
|
29
|
+
} catch {
|
|
30
|
+
main();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function main() {
|
|
34
|
+
try {
|
|
35
|
+
const projectRoot = payload.cwd || payload.project_root || process.cwd();
|
|
36
|
+
const { buildContextBlock } = require(path.join(__dirname, '..', '..', 'scripts', 'memory', 'inject'));
|
|
37
|
+
|
|
38
|
+
const block = buildContextBlock({ projectRoot });
|
|
39
|
+
if (!block || !block.text) {
|
|
40
|
+
process.exit(0);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Emit as additional context — non-blocking, advisory
|
|
44
|
+
const output = {
|
|
45
|
+
additionalContext: block.text,
|
|
46
|
+
meta: {
|
|
47
|
+
source: 'kodelyth-memory',
|
|
48
|
+
memoryCount: block.memoryCount,
|
|
49
|
+
projectMemoryCount: block.projectMemoryCount,
|
|
50
|
+
patternCount: block.patternCount,
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
process.stdout.write(JSON.stringify(output));
|
|
54
|
+
process.exit(0);
|
|
55
|
+
} catch (err) {
|
|
56
|
+
// Never crash a session because memory hook failed — log to stderr and continue
|
|
57
|
+
process.stderr.write(`kodelyth-memory inject: ${err.message}\n`);
|
|
58
|
+
process.exit(0);
|
|
59
|
+
}
|
|
60
|
+
}
|
package/install.ps1
CHANGED
|
@@ -21,7 +21,7 @@ $ErrorActionPreference = "Stop"
|
|
|
21
21
|
# ── Banner ────────────────────────────────────────────────────────────────────
|
|
22
22
|
Write-Host ""
|
|
23
23
|
Write-Host " Kodelyth ECC — Production-grade AI coding agent toolkit" -ForegroundColor Cyan
|
|
24
|
-
Write-Host "
|
|
24
|
+
Write-Host " 59 agents · 188 skills · 80 commands · 18+ hooks · intent routing · local memory" -ForegroundColor Gray
|
|
25
25
|
Write-Host ""
|
|
26
26
|
|
|
27
27
|
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
@@ -131,8 +131,8 @@ Write-Host "Installing components..." -ForegroundColor Bold
|
|
|
131
131
|
|
|
132
132
|
switch ($Target) {
|
|
133
133
|
"claude-home" {
|
|
134
|
-
Install-Dir "$ScriptDir\agents" $AgentsDest "Agents (
|
|
135
|
-
Install-Dir "$ScriptDir\skills" $SkillsDest "Skills (
|
|
134
|
+
Install-Dir "$ScriptDir\agents" $AgentsDest "Agents (58)"
|
|
135
|
+
Install-Dir "$ScriptDir\skills" $SkillsDest "Skills (187)"
|
|
136
136
|
Install-Dir "$ScriptDir\commands" $CommandsDest "Commands (79)"
|
|
137
137
|
|
|
138
138
|
# Hooks
|
|
@@ -162,8 +162,8 @@ switch ($Target) {
|
|
|
162
162
|
Write-Host " [OK] CLAUDE.md + SOUL.md" -ForegroundColor Green
|
|
163
163
|
}
|
|
164
164
|
{ $_ -in "windsurf-project","windsurf-home" } {
|
|
165
|
-
Install-Dir "$ScriptDir\agents" $AgentsDest "Agents (
|
|
166
|
-
Install-Dir "$ScriptDir\skills" $SkillsDest "Skills (
|
|
165
|
+
Install-Dir "$ScriptDir\agents" $AgentsDest "Agents (58)"
|
|
166
|
+
Install-Dir "$ScriptDir\skills" $SkillsDest "Skills (187)"
|
|
167
167
|
Install-Flat "$ScriptDir\rules" $RulesDest "Rules"
|
|
168
168
|
|
|
169
169
|
# Generate .windsurfrules from all common rules
|
|
@@ -176,17 +176,17 @@ switch ($Target) {
|
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
178
|
"antigravity" {
|
|
179
|
-
Install-Dir "$ScriptDir\agents" $AgentsDest "Agents -> skills (
|
|
179
|
+
Install-Dir "$ScriptDir\agents" $AgentsDest "Agents -> skills (58)"
|
|
180
180
|
Install-Dir "$ScriptDir\commands" $CommandsDest "Commands -> workflows (79)"
|
|
181
181
|
Install-Flat "$ScriptDir\rules" $RulesDest "Rules"
|
|
182
182
|
}
|
|
183
183
|
"cursor-project" {
|
|
184
184
|
Install-Flat "$ScriptDir\rules" $RulesDest "Rules"
|
|
185
|
-
Install-Dir "$ScriptDir\skills" $SkillsDest "Skills (
|
|
185
|
+
Install-Dir "$ScriptDir\skills" $SkillsDest "Skills (187)"
|
|
186
186
|
}
|
|
187
187
|
"codex-home" {
|
|
188
|
-
Install-Dir "$ScriptDir\agents" $AgentsDest "Agents (
|
|
189
|
-
Install-Dir "$ScriptDir\skills" $SkillsDest "Skills (
|
|
188
|
+
Install-Dir "$ScriptDir\agents" $AgentsDest "Agents (58)"
|
|
189
|
+
Install-Dir "$ScriptDir\skills" $SkillsDest "Skills (187)"
|
|
190
190
|
Install-Dir "$ScriptDir\commands" $CommandsDest "Commands (79)"
|
|
191
191
|
Install-Flat "$ScriptDir\rules" $RulesDest "Rules"
|
|
192
192
|
}
|
|
@@ -219,11 +219,30 @@ switch ($Target) {
|
|
|
219
219
|
Write-Host " 2. Type: /kodelyth-quickstart"
|
|
220
220
|
Write-Host " 3. Or: use kodelyth-advisor"
|
|
221
221
|
}
|
|
222
|
+
{ $_ -in "windsurf-project","windsurf-home" } {
|
|
223
|
+
Write-Host " 1. Open the project in Windsurf"
|
|
224
|
+
Write-Host " 2. Cascade auto-loads .windsurfrules on every session"
|
|
225
|
+
Write-Host " 3. Try: use kodelyth-advisor"
|
|
226
|
+
}
|
|
227
|
+
"cursor-project" {
|
|
228
|
+
Write-Host " 1. Open the project in Cursor"
|
|
229
|
+
Write-Host " 2. Rules and skills are now active in chat"
|
|
230
|
+
Write-Host " 3. Try: use kodelyth-advisor"
|
|
231
|
+
}
|
|
232
|
+
"codex-home" {
|
|
233
|
+
Write-Host " 1. Restart Codex CLI (codex)"
|
|
234
|
+
Write-Host " 2. All 59 agents and 188 skills are now available"
|
|
235
|
+
Write-Host " 3. Try: use kodelyth-advisor"
|
|
236
|
+
}
|
|
222
237
|
"antigravity" {
|
|
223
238
|
Write-Host " 1. Open your project in Antigravity"
|
|
224
239
|
Write-Host " 2. Agents are available as Skills"
|
|
225
240
|
Write-Host " 3. Commands are available as Workflows"
|
|
226
241
|
}
|
|
242
|
+
"opencode" {
|
|
243
|
+
Write-Host " 1. Open the project in OpenCode"
|
|
244
|
+
Write-Host " 2. Rules in .opencode/rules/ are now loaded"
|
|
245
|
+
}
|
|
227
246
|
default {
|
|
228
247
|
Write-Host " 1. Restart your AI coding agent"
|
|
229
248
|
Write-Host " 2. Agents, skills, and rules are now active"
|