@ekkos/cli 1.3.1 → 1.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/dist/capture/jsonl-rewriter.d.ts +1 -1
  2. package/dist/capture/jsonl-rewriter.js +3 -3
  3. package/dist/capture/transcript-repair.d.ts +2 -2
  4. package/dist/capture/transcript-repair.js +2 -2
  5. package/dist/commands/claw.d.ts +13 -0
  6. package/dist/commands/claw.js +253 -0
  7. package/dist/commands/dashboard.js +742 -118
  8. package/dist/commands/doctor.d.ts +3 -3
  9. package/dist/commands/doctor.js +6 -79
  10. package/dist/commands/gemini.d.ts +19 -0
  11. package/dist/commands/gemini.js +193 -0
  12. package/dist/commands/init.d.ts +1 -0
  13. package/dist/commands/init.js +56 -41
  14. package/dist/commands/run.d.ts +0 -1
  15. package/dist/commands/run.js +288 -263
  16. package/dist/commands/scan.d.ts +21 -0
  17. package/dist/commands/scan.js +386 -0
  18. package/dist/commands/status.d.ts +4 -1
  19. package/dist/commands/status.js +165 -27
  20. package/dist/commands/swarm-dashboard.js +156 -28
  21. package/dist/commands/swarm.d.ts +1 -1
  22. package/dist/commands/swarm.js +1 -1
  23. package/dist/commands/test-claude.d.ts +2 -2
  24. package/dist/commands/test-claude.js +3 -3
  25. package/dist/deploy/index.d.ts +0 -2
  26. package/dist/deploy/index.js +0 -2
  27. package/dist/deploy/settings.d.ts +6 -5
  28. package/dist/deploy/settings.js +64 -16
  29. package/dist/deploy/skills.js +1 -2
  30. package/dist/index.js +86 -96
  31. package/dist/lib/usage-parser.d.ts +1 -1
  32. package/dist/lib/usage-parser.js +9 -6
  33. package/dist/local/index.d.ts +14 -0
  34. package/dist/local/index.js +28 -0
  35. package/dist/local/local-embeddings.d.ts +49 -0
  36. package/dist/local/local-embeddings.js +232 -0
  37. package/dist/local/offline-fallback.d.ts +44 -0
  38. package/dist/local/offline-fallback.js +159 -0
  39. package/dist/local/sqlite-store.d.ts +126 -0
  40. package/dist/local/sqlite-store.js +393 -0
  41. package/dist/local/sync-engine.d.ts +42 -0
  42. package/dist/local/sync-engine.js +223 -0
  43. package/dist/utils/platform.d.ts +5 -1
  44. package/dist/utils/platform.js +24 -4
  45. package/dist/utils/proxy-url.d.ts +21 -0
  46. package/dist/utils/proxy-url.js +34 -0
  47. package/dist/utils/state.d.ts +1 -1
  48. package/dist/utils/state.js +11 -3
  49. package/dist/utils/templates.js +1 -1
  50. package/package.json +11 -4
  51. package/templates/CLAUDE.md +49 -107
  52. package/dist/agent/daemon.d.ts +0 -130
  53. package/dist/agent/daemon.js +0 -606
  54. package/dist/agent/health-check.d.ts +0 -35
  55. package/dist/agent/health-check.js +0 -243
  56. package/dist/agent/pty-runner.d.ts +0 -53
  57. package/dist/agent/pty-runner.js +0 -190
  58. package/dist/commands/agent.d.ts +0 -50
  59. package/dist/commands/agent.js +0 -544
  60. package/dist/commands/setup-remote.d.ts +0 -20
  61. package/dist/commands/setup-remote.js +0 -582
  62. package/dist/utils/verify-remote-terminal.d.ts +0 -10
  63. package/dist/utils/verify-remote-terminal.js +0 -415
  64. package/templates/README.md +0 -378
  65. package/templates/claude-plugins/PHASE2_COMPLETION.md +0 -346
  66. package/templates/claude-plugins/PLUGIN_PROPOSALS.md +0 -1776
  67. package/templates/claude-plugins/README.md +0 -587
  68. package/templates/claude-plugins/agents/code-reviewer.json +0 -14
  69. package/templates/claude-plugins/agents/debug-detective.json +0 -15
  70. package/templates/claude-plugins/agents/git-companion.json +0 -14
  71. package/templates/claude-plugins/blog-manager/.claude-plugin/plugin.json +0 -8
  72. package/templates/claude-plugins/blog-manager/commands/blog.md +0 -691
  73. package/templates/claude-plugins/golden-loop-monitor/.claude-plugin/plugin.json +0 -8
  74. package/templates/claude-plugins/golden-loop-monitor/commands/loop-status.md +0 -434
  75. package/templates/claude-plugins/learning-tracker/.claude-plugin/plugin.json +0 -8
  76. package/templates/claude-plugins/learning-tracker/commands/my-patterns.md +0 -282
  77. package/templates/claude-plugins/memory-lens/.claude-plugin/plugin.json +0 -8
  78. package/templates/claude-plugins/memory-lens/commands/memory-search.md +0 -181
  79. package/templates/claude-plugins/pattern-coach/.claude-plugin/plugin.json +0 -8
  80. package/templates/claude-plugins/pattern-coach/commands/forge.md +0 -365
  81. package/templates/claude-plugins/project-schema-validator/.claude-plugin/plugin.json +0 -8
  82. package/templates/claude-plugins/project-schema-validator/commands/validate-schema.md +0 -582
  83. package/templates/claude-plugins-admin/AGENT_TEAM_PROPOSALS.md +0 -819
  84. package/templates/claude-plugins-admin/README.md +0 -446
  85. package/templates/claude-plugins-admin/autonomous-admin-agent/.claude-plugin/plugin.json +0 -8
  86. package/templates/claude-plugins-admin/autonomous-admin-agent/commands/agent.md +0 -595
  87. package/templates/claude-plugins-admin/backend-agent/.claude-plugin/plugin.json +0 -8
  88. package/templates/claude-plugins-admin/backend-agent/commands/backend.md +0 -798
  89. package/templates/claude-plugins-admin/deploy-guardian/.claude-plugin/plugin.json +0 -8
  90. package/templates/claude-plugins-admin/deploy-guardian/commands/deploy.md +0 -554
  91. package/templates/claude-plugins-admin/frontend-agent/.claude-plugin/plugin.json +0 -8
  92. package/templates/claude-plugins-admin/frontend-agent/commands/frontend.md +0 -881
  93. package/templates/claude-plugins-admin/mcp-server-manager/.claude-plugin/plugin.json +0 -8
  94. package/templates/claude-plugins-admin/mcp-server-manager/commands/mcp.md +0 -85
  95. package/templates/claude-plugins-admin/memory-system-monitor/.claude-plugin/plugin.json +0 -8
  96. package/templates/claude-plugins-admin/memory-system-monitor/commands/memory-health.md +0 -569
  97. package/templates/claude-plugins-admin/qa-agent/.claude-plugin/plugin.json +0 -8
  98. package/templates/claude-plugins-admin/qa-agent/commands/qa.md +0 -863
  99. package/templates/claude-plugins-admin/tech-lead-agent/.claude-plugin/plugin.json +0 -8
  100. package/templates/claude-plugins-admin/tech-lead-agent/commands/lead.md +0 -732
  101. package/templates/commands/continue.md +0 -47
  102. package/templates/cursor-rules/ekkos-memory.md +0 -127
  103. package/templates/ekkos-manifest.json +0 -223
  104. package/templates/helpers/json-parse.cjs +0 -101
  105. package/templates/hooks-node/lib/state.js +0 -187
  106. package/templates/hooks-node/stop.js +0 -416
  107. package/templates/hooks-node/user-prompt-submit.js +0 -337
  108. package/templates/plan-template.md +0 -306
  109. package/templates/rules/00-hooks-contract.mdc +0 -89
  110. package/templates/rules/30-ekkos-core.mdc +0 -188
  111. package/templates/rules/31-ekkos-messages.mdc +0 -78
  112. package/templates/shared/hooks-enabled.json +0 -22
  113. package/templates/shared/session-words.json +0 -45
  114. package/templates/skills/ekkOS_Deep_Recall/Skill.md +0 -282
  115. package/templates/skills/ekkOS_Learn/Skill.md +0 -265
  116. package/templates/skills/ekkOS_Memory_First/Skill.md +0 -206
  117. package/templates/skills/ekkOS_Plan_Assist/Skill.md +0 -302
  118. package/templates/skills/ekkOS_Preferences/Skill.md +0 -247
  119. package/templates/skills/ekkOS_Reflect/Skill.md +0 -257
  120. package/templates/skills/ekkOS_Safety/Skill.md +0 -265
  121. package/templates/skills/ekkOS_Schema/Skill.md +0 -251
  122. package/templates/skills/ekkOS_Summary/Skill.md +0 -257
  123. package/templates/spec-template.md +0 -159
  124. package/templates/windsurf-rules/ekkos-memory.md +0 -127
  125. package/templates/windsurf-skills/README.md +0 -58
  126. package/templates/windsurf-skills/ekkos-continue/SKILL.md +0 -81
  127. package/templates/windsurf-skills/ekkos-golden-loop/SKILL.md +0 -225
  128. package/templates/windsurf-skills/ekkos-insights/SKILL.md +0 -138
  129. package/templates/windsurf-skills/ekkos-recall/SKILL.md +0 -96
  130. package/templates/windsurf-skills/ekkos-safety/SKILL.md +0 -89
  131. package/templates/windsurf-skills/ekkos-vault/SKILL.md +0 -86
@@ -1,47 +0,0 @@
1
- # /continue
2
-
3
- Restore your last 5 turns after running `/clear`.
4
-
5
- ## Usage
6
-
7
- ```
8
- /clear # First: free up context
9
- /continue # Then: restore last 5 turns
10
- ```
11
-
12
- ## What Happens
13
-
14
- 1. Hook detects `/continue`
15
- 2. Fetches last 5 turns from ekkOS API
16
- 3. Injects them as context
17
- 4. Claude continues seamlessly
18
-
19
- ## Why This Exists
20
-
21
- When context gets full (90%+), you need to `/clear` but don't want to lose your work. This command restores just enough context (5 turns) to continue working without re-explaining everything.
22
-
23
- ## The Flow
24
-
25
- ```
26
- Work normally until context ~90%
27
-
28
- Run: /clear (frees context)
29
-
30
- Run: /continue (restores 5 turns)
31
-
32
- Keep working
33
- ```
34
-
35
- ## Example
36
-
37
- ```
38
- [Context at 92%]
39
-
40
- You: /clear
41
- Claude: Context cleared.
42
-
43
- You: /continue
44
- Hook: ✓ Session continued (5 turns restored)
45
-
46
- Claude: ✓ **Continuing** - We were working on the /continue command...
47
- ```
@@ -1,127 +0,0 @@
1
- ---
2
- description: "ekkOS Memory — 11-layer cognitive memory with 29 MCP tools"
3
- alwaysApply: true
4
- ---
5
-
6
- # ekkOS Memory System
7
-
8
- You have access to **ekkOS memory** via 29 MCP tools. This is an 11-layer cognitive memory system that makes AI smarter over time by learning from past sessions.
9
-
10
- ## MANDATORY RULES
11
-
12
- ### RULE 1: SEARCH BEFORE ANSWERING
13
- Before answering ANY technical question, call `ekkOS_Search` first.
14
-
15
- ### RULE 2: ACKNOWLEDGE RETRIEVED PATTERNS
16
- When patterns are retrieved, acknowledge each one:
17
- ```
18
- [ekkOS_SELECT]
19
- - id: <pattern_id>
20
- reason: <why using>
21
- confidence: <0.0-1.0>
22
- [/ekkOS_SELECT]
23
-
24
- [ekkOS_SKIP]
25
- - id: <pattern_id>
26
- reason: <why not relevant>
27
- [/ekkOS_SKIP]
28
- ```
29
-
30
- Suppress SELECT/SKIP blocks for non-technical turns (acknowledgments, affirmations).
31
-
32
- ### RULE 3: FORGE WHAT YOU LEARN
33
- When you fix a bug, get corrected, or learn something new, call `ekkOS_Forge` immediately.
34
- When something DOESN'T work, forge it as an anti-pattern.
35
-
36
- ## MCP Tools — 29 Visible
37
-
38
- ### Core Memory (6)
39
- | Tool | Description |
40
- |------|-------------|
41
- | `ekkOS_Search` | Search across all 11 memory layers |
42
- | `ekkOS_Forge` | Create pattern from learned solution |
43
- | `ekkOS_Track` | Track when a pattern is applied |
44
- | `ekkOS_Outcome` | Record if pattern worked or failed |
45
- | `ekkOS_Stats` | Get statistics for all layers |
46
- | `ekkOS_Context` | Get relevant context for a task |
47
-
48
- ### Retrieval (4)
49
- | Tool | Description |
50
- |------|-------------|
51
- | `ekkOS_Codebase` | Search project code embeddings |
52
- | `ekkOS_Recall` | Recall past conversations by time |
53
- | `ekkOS_PreserveContext` | Preserve working memory before compaction |
54
- | `ekkOS_RestoreContext` | Restore context after compaction |
55
-
56
- ### Directives (4)
57
- | Tool | Description |
58
- |------|-------------|
59
- | `ekkOS_Directive` | Create MUST/NEVER/PREFER/AVOID rules |
60
- | `ekkOS_UpdateDirective` | Update an existing directive |
61
- | `ekkOS_DeleteDirective` | Remove a directive |
62
- | `ekkOS_UniversalDirectives` | Get directives that apply across all projects |
63
-
64
- ### Utility (5)
65
- | Tool | Description |
66
- |------|-------------|
67
- | `ekkOS_Summary` | Get summary of recent memory activity |
68
- | `ekkOS_Conflict` | Check for conflicts before destructive actions |
69
- | `ekkOS_Export` | Export patterns, directives, plans as JSON backup |
70
- | `ekkOS_Import` | Import memory from backup (auto-deduplication) |
71
- | `ekkOS_Health` | System health check |
72
-
73
- ### Plans (5)
74
- | Tool | Description |
75
- |------|-------------|
76
- | `ekkOS_Plan` | Create structured task plan |
77
- | `ekkOS_Plans` | List your plans |
78
- | `ekkOS_PlanStatus` | Update plan status |
79
- | `ekkOS_PlanStep` | Mark step complete/incomplete |
80
- | `ekkOS_Generate` | AI-generate plan from context |
81
-
82
- ### Secrets (5)
83
- | Tool | Description |
84
- |------|-------------|
85
- | `ekkOS_StoreSecret` | Encrypt and store sensitive data |
86
- | `ekkOS_GetSecret` | Retrieve and decrypt a secret |
87
- | `ekkOS_ListSecrets` | List secrets metadata (no values exposed) |
88
- | `ekkOS_DeleteSecret` | Permanently delete a secret |
89
- | `ekkOS_RotateSecret` | Update a secret with a new value |
90
-
91
- ## 11-Layer Architecture
92
-
93
- | # | Layer | Purpose |
94
- |---|-------|---------|
95
- | 1 | Working | Current session state |
96
- | 2 | Episodic | Past conversations |
97
- | 3 | Semantic | Embeddings & knowledge |
98
- | 4 | Patterns | Proven solutions |
99
- | 5 | Procedural | Step-by-step guides |
100
- | 6 | Collective | Cross-project wisdom |
101
- | 7 | Meta | Pattern effectiveness |
102
- | 8 | Codebase | Project-specific code |
103
- | 9 | Directives | User rules (MUST/NEVER/PREFER/AVOID) |
104
- | 10 | Conflict | Auto-resolves contradictions |
105
- | 11 | Secrets | Encrypted credentials (AES-256-GCM) |
106
-
107
- ## When To Use What
108
-
109
- | Tool | Trigger |
110
- |------|---------|
111
- | `ekkOS_Search` | Technical question, past discussion, architecture, debugging |
112
- | `ekkOS_Forge` | Bug fixed, better approach, gotcha, correction, anti-pattern |
113
- | `ekkOS_Directive` | User says "always" → MUST, "never" → NEVER, "prefer" → PREFER, "avoid" → AVOID |
114
- | `ekkOS_Conflict` | Before delete, deploy, config change, destructive commands |
115
- | Plan tools | Task has 3+ steps, complex feature request |
116
- | Secret tools | User shares API key/token/password, need stored credentials |
117
- | `ekkOS_Recall` | "yesterday", "last week", "remember when", "what did we discuss" |
118
-
119
- ## Response Format
120
-
121
- End every response with:
122
- ```
123
- ---
124
- 🧠 **ekkOS_™** · 📅 YYYY-MM-DD H:MM AM/PM TZ
125
- ```
126
-
127
- For more info: https://docs.ekkos.dev
@@ -1,223 +0,0 @@
1
- {
2
- "$schema": "https://ekkos.dev/schemas/manifest-v1.json",
3
- "manifestVersion": "1.0.0",
4
- "generatedAt": "2026-02-20T07:39:17.071Z",
5
- "platforms": {
6
- "darwin": {
7
- "configDir": "~/.ekkos",
8
- "globalHooksDir": "~/.claude/hooks",
9
- "shell": "bash"
10
- },
11
- "linux": {
12
- "configDir": "~/.ekkos",
13
- "globalHooksDir": "~/.claude/hooks",
14
- "shell": "bash"
15
- },
16
- "win32": {
17
- "configDir": "%USERPROFILE%\\.ekkos",
18
- "globalHooksDir": "%USERPROFILE%\\.claude\\hooks",
19
- "shell": "powershell"
20
- }
21
- },
22
- "files": {
23
- "managed": [
24
- {
25
- "source": "shared/session-words.json",
26
- "destination": ".defaults/session-words.json",
27
- "description": "Default session word lists (managed fallback)",
28
- "checksum": "c64af03b9ae58d8c94e71886f80e590ad3a72fb2dcdbe02812789fecb4773e1a",
29
- "overwrite": "always"
30
- },
31
- {
32
- "source": "shared/hooks-enabled.json",
33
- "destination": ".defaults/hooks-enabled.json",
34
- "description": "Default hooks enablement config (managed fallback)",
35
- "checksum": "74b833a1979f1b9467be6dcdeecc024073a4f3c02625b0751f4b1f9d53f143a3",
36
- "overwrite": "always"
37
- }
38
- ],
39
- "helpers": [
40
- {
41
- "source": "helpers/json-parse.cjs",
42
- "destination": ".helpers/json-parse.cjs",
43
- "description": "Node-based JSON parser (replaces jq dependency)",
44
- "checksum": "e421977262b3bffcbec9f6f7a172df6f998f3b4deac64d478ef5a0a17034b026",
45
- "executable": true,
46
- "overwrite": "always"
47
- }
48
- ],
49
- "userEditable": [
50
- {
51
- "source": "shared/session-words.json",
52
- "destination": "session-words.json",
53
- "description": "User-customizable session word lists",
54
- "checksum": "c64af03b9ae58d8c94e71886f80e590ad3a72fb2dcdbe02812789fecb4773e1a",
55
- "overwrite": "createOnly"
56
- },
57
- {
58
- "source": "shared/hooks-enabled.json",
59
- "destination": "hooks-enabled.json",
60
- "description": "User-controlled hook enablement",
61
- "checksum": "74b833a1979f1b9467be6dcdeecc024073a4f3c02625b0751f4b1f9d53f143a3",
62
- "overwrite": "createOnly"
63
- }
64
- ],
65
- "hooks": {
66
- "bash": [
67
- {
68
- "source": "hooks/user-prompt-submit.sh",
69
- "destination": "user-prompt-submit.sh",
70
- "description": "User prompt submit hook (Unix)",
71
- "checksum": "c53b621f3c64031f61b7ca1b3bf5ba4bec895b6a39aa7627422f0f2a2d26ab7d",
72
- "executable": true
73
- },
74
- {
75
- "source": "hooks/stop.sh",
76
- "destination": "stop.sh",
77
- "description": "Session stop hook (Unix)",
78
- "checksum": "f3b4495c0c2bbdf5bfef762568faec7b70b41b463dad4c88b37cf7ee32b5257d",
79
- "executable": true
80
- },
81
- {
82
- "source": "hooks/session-start.sh",
83
- "destination": "session-start.sh",
84
- "description": "Session start hook (Unix)",
85
- "checksum": "8d17fd3203045589f0c410f465b0d1e98d6ed24dc3bc99f44878e44e9501a22d",
86
- "executable": true
87
- },
88
- {
89
- "source": "hooks/assistant-response.sh",
90
- "destination": "assistant-response.sh",
91
- "description": "Assistant response hook (Unix)",
92
- "checksum": "99400adf6ced406f0295c25db3b8fb892212ad3ba625f427c042d8526ac8f6f7",
93
- "executable": true
94
- }
95
- ],
96
- "powershell": [
97
- {
98
- "source": "hooks/user-prompt-submit.ps1",
99
- "destination": "user-prompt-submit.ps1",
100
- "description": "User prompt submit hook (Windows)",
101
- "checksum": "ba1090ed7a4e7deef1267b52474225669a9c966b9adf596b31865c2dca1dc749"
102
- },
103
- {
104
- "source": "hooks/stop.ps1",
105
- "destination": "stop.ps1",
106
- "description": "Session stop hook (Windows)",
107
- "checksum": "c4f0191ac28ced0410ea560197ab3b0a7e2de83363a789731d64620bc605564d"
108
- },
109
- {
110
- "source": "hooks/session-start.ps1",
111
- "destination": "session-start.ps1",
112
- "description": "Session start hook (Windows)",
113
- "checksum": "1930bda7c517054531ff3ad78e8cce7e60d57f5b3884728da0d7cf1cc5c54ac4"
114
- },
115
- {
116
- "source": "hooks/assistant-response.ps1",
117
- "destination": "assistant-response.ps1",
118
- "description": "Assistant response hook (Windows)",
119
- "checksum": "680e6d7c597f90fb54bc86d173f4c145093eb21352b30c7d6afbe19d1d5fdce4"
120
- }
121
- ],
122
- "lib": [
123
- {
124
- "source": "hooks/lib/contract.sh",
125
- "destination": "lib/contract.sh",
126
- "description": "Hook contract library",
127
- "checksum": "3ef16930ba10cd37a1c5fa8469ec13a6a84cadb882d3f9a96c72da875ba07fc7",
128
- "executable": true
129
- },
130
- {
131
- "source": "hooks/lib/state.sh",
132
- "destination": "lib/state.sh",
133
- "description": "Hook state management library",
134
- "checksum": "99223ce9b869d78762084ff184327fa2814af7a16e5f2ac9619af43b5e551d7c",
135
- "executable": true
136
- }
137
- ]
138
- }
139
- },
140
- "projectStubs": {
141
- "description": "Delegating stub hooks for project-level installation. These source global hooks first, then load project-specific overrides.",
142
- "bash": [
143
- {
144
- "source": "project-stubs/user-prompt-submit.sh",
145
- "destination": "user-prompt-submit.sh",
146
- "description": "Project delegating stub for user-prompt-submit (Unix)",
147
- "checksum": "47cc6b45dbb027e321c136f7c0935bae0d3dc349f01912fbe42ae27d382e297d",
148
- "executable": true
149
- },
150
- {
151
- "source": "project-stubs/stop.sh",
152
- "destination": "stop.sh",
153
- "description": "Project delegating stub for stop (Unix)",
154
- "checksum": "a429c5ee596e6c975df32feb8ba952c77c0492d91bd9cd80f9eac2e721040eb4",
155
- "executable": true
156
- },
157
- {
158
- "source": "project-stubs/session-start.sh",
159
- "destination": "session-start.sh",
160
- "description": "Project delegating stub for session-start (Unix)",
161
- "checksum": "189379e81e000153d057e49afd71791d28a6b73baab4b49b39de34918a00c493",
162
- "executable": true
163
- }
164
- ],
165
- "powershell": [
166
- {
167
- "source": "project-stubs/user-prompt-submit.ps1",
168
- "destination": "user-prompt-submit.ps1",
169
- "description": "Project delegating stub for user-prompt-submit (Windows)",
170
- "checksum": "86cfea6a6e1181fc6b9180e82a3e34e1ba8e8b412c65bdf013d2367ea8b93283"
171
- },
172
- {
173
- "source": "project-stubs/stop.ps1",
174
- "destination": "stop.ps1",
175
- "description": "Project delegating stub for stop (Windows)",
176
- "checksum": "042f815ed455c5b5e51291b8740deafaea827c594695b270f4d4e4e5086bc234"
177
- },
178
- {
179
- "source": "project-stubs/session-start.ps1",
180
- "destination": "session-start.ps1",
181
- "description": "Project delegating stub for session-start (Windows)",
182
- "checksum": "14081806c7ca63a67999314f31e14a6c1293e57a8ce64335122f359e3bb8fba4"
183
- }
184
- ]
185
- },
186
- "cli": {
187
- "minVersion": "0.2.9",
188
- "legacySupported": true,
189
- "requiredCommands": {
190
- "0.2.9": [
191
- "run",
192
- "config"
193
- ],
194
- "0.3.0": [
195
- "run",
196
- "config",
197
- "hooks"
198
- ]
199
- }
200
- },
201
- "validation": {
202
- "requiredFiles": [
203
- "shared/session-words.json",
204
- "shared/hooks-enabled.json",
205
- "helpers/json-parse.cjs",
206
- "hooks/user-prompt-submit.sh",
207
- "hooks/user-prompt-submit.ps1",
208
- "hooks/stop.sh",
209
- "hooks/stop.ps1",
210
- "hooks/session-start.sh",
211
- "hooks/session-start.ps1",
212
- "hooks/assistant-response.sh",
213
- "hooks/assistant-response.ps1",
214
- "project-stubs/user-prompt-submit.sh",
215
- "project-stubs/user-prompt-submit.ps1",
216
- "project-stubs/stop.sh",
217
- "project-stubs/stop.ps1",
218
- "project-stubs/session-start.sh",
219
- "project-stubs/session-start.ps1"
220
- ],
221
- "checksumAlgorithm": "sha256"
222
- }
223
- }
@@ -1,101 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * json-parse.cjs - Minimal JSON parser for ekkOS hooks
4
- * Eliminates jq dependency for cross-platform compatibility
5
- *
6
- * Usage: json-parse.cjs <file> [path]
7
- *
8
- * Examples:
9
- * json-parse.cjs config.json # Output entire file
10
- * json-parse.cjs config.json .apiKey # Output single value
11
- * json-parse.cjs words.json .adjectives # Output array (one per line)
12
- * json-parse.cjs hooks.json .targets.claude.stop # Nested path
13
- *
14
- * Exit codes:
15
- * 0 - Success (including empty/null result)
16
- * 1 - Error (file not found, invalid JSON, etc.)
17
- */
18
-
19
- const fs = require('fs');
20
- const path = require('path');
21
-
22
- const args = process.argv.slice(2);
23
-
24
- if (args.length < 1) {
25
- console.error('Usage: json-parse.cjs <file> [path]');
26
- console.error('Example: json-parse.cjs config.json .apiKey');
27
- process.exit(1);
28
- }
29
-
30
- const filePath = args[0];
31
- const jsonPath = args[1] || null;
32
-
33
- // Check file exists
34
- if (!fs.existsSync(filePath)) {
35
- console.error(`Error: File not found: ${filePath}`);
36
- process.exit(1);
37
- }
38
-
39
- let data;
40
- try {
41
- const content = fs.readFileSync(filePath, 'utf8');
42
- data = JSON.parse(content);
43
- } catch (err) {
44
- console.error(`Error: Failed to parse JSON: ${err.message}`);
45
- process.exit(1);
46
- }
47
-
48
- // If no path specified, output entire JSON
49
- if (!jsonPath) {
50
- console.log(JSON.stringify(data, null, 2));
51
- process.exit(0);
52
- }
53
-
54
- // Parse path and extract value
55
- // Supports: .foo.bar, .foo[0], .foo.bar[1].baz
56
- function extractValue(obj, pathStr) {
57
- if (!pathStr || pathStr === '.') return obj;
58
-
59
- // Remove leading dot if present
60
- const cleanPath = pathStr.startsWith('.') ? pathStr.slice(1) : pathStr;
61
- if (!cleanPath) return obj;
62
-
63
- // Split on . and [ but keep the brackets for array access
64
- const parts = cleanPath.split(/\.|\[|\]/).filter(Boolean);
65
-
66
- let result = obj;
67
- for (const part of parts) {
68
- if (result === undefined || result === null) {
69
- return undefined;
70
- }
71
- result = result[part];
72
- }
73
- return result;
74
- }
75
-
76
- const result = extractValue(data, jsonPath);
77
-
78
- // Handle different result types
79
- if (result === undefined || result === null) {
80
- // Empty output, exit 0 (not an error - just no value)
81
- process.exit(0);
82
- }
83
-
84
- if (Array.isArray(result)) {
85
- // Output array items one per line (like jq -r '.[]')
86
- for (const item of result) {
87
- if (typeof item === 'object') {
88
- console.log(JSON.stringify(item));
89
- } else {
90
- console.log(item);
91
- }
92
- }
93
- } else if (typeof result === 'object') {
94
- console.log(JSON.stringify(result, null, 2));
95
- } else if (typeof result === 'boolean') {
96
- console.log(result ? 'true' : 'false');
97
- } else {
98
- console.log(result);
99
- }
100
-
101
- process.exit(0);
@@ -1,187 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * ekkOS™ Hook State Management Library (Node.js - Cross-Platform)
4
- * Shared state functions for coordinating between hooks
5
- * Works on Windows, macOS, and Linux without bash/curl/jq dependencies
6
- */
7
-
8
- const fs = require('fs');
9
- const path = require('path');
10
- const crypto = require('crypto');
11
-
12
- // Get project root (where .claude directory lives)
13
- function getProjectRoot() {
14
- const scriptDir = __dirname;
15
- return path.dirname(path.dirname(path.dirname(scriptDir)));
16
- }
17
-
18
- const PROJECT_ROOT = getProjectRoot();
19
- const STATE_DIR = path.join(PROJECT_ROOT, '.claude', 'state');
20
-
21
- // Ensure state directory exists
22
- function ensureStateDir() {
23
- if (!fs.existsSync(STATE_DIR)) {
24
- fs.mkdirSync(STATE_DIR, { recursive: true });
25
- }
26
- }
27
-
28
- // ═══════════════════════════════════════════════════════════════════════════
29
- // State File Management
30
- // ═══════════════════════════════════════════════════════════════════════════
31
-
32
- function savePatterns(sessionId, patterns, modelUsed) {
33
- ensureStateDir();
34
- const stateFile = path.join(STATE_DIR, `patterns-${sessionId}.json`);
35
-
36
- const data = {
37
- patterns: patterns,
38
- model_used: modelUsed,
39
- saved_at: new Date().toISOString()
40
- };
41
-
42
- fs.writeFileSync(stateFile, JSON.stringify(data, null, 2));
43
- }
44
-
45
- function loadPatterns(sessionId) {
46
- const stateFile = path.join(STATE_DIR, `patterns-${sessionId}.json`);
47
-
48
- if (fs.existsSync(stateFile)) {
49
- try {
50
- return JSON.parse(fs.readFileSync(stateFile, 'utf8'));
51
- } catch {
52
- return {};
53
- }
54
- }
55
- return {};
56
- }
57
-
58
- function clearPatterns(sessionId) {
59
- const stateFile = path.join(STATE_DIR, `patterns-${sessionId}.json`);
60
- if (fs.existsSync(stateFile)) {
61
- fs.unlinkSync(stateFile);
62
- }
63
- }
64
-
65
- // ═══════════════════════════════════════════════════════════════════════════
66
- // Capture Deduplication
67
- // ═══════════════════════════════════════════════════════════════════════════
68
-
69
- function generateTurnHash(userQuery, assistantResponse) {
70
- return crypto.createHash('md5').update(`${userQuery}${assistantResponse}`).digest('hex');
71
- }
72
-
73
- function wasTurnCaptured(sessionId, turnHash) {
74
- const captureLog = path.join(STATE_DIR, `captures-${sessionId}.log`);
75
-
76
- if (fs.existsSync(captureLog)) {
77
- const hashes = fs.readFileSync(captureLog, 'utf8').split('\n');
78
- return hashes.includes(turnHash);
79
- }
80
- return false;
81
- }
82
-
83
- function markTurnCaptured(sessionId, turnHash) {
84
- ensureStateDir();
85
- const captureLog = path.join(STATE_DIR, `captures-${sessionId}.log`);
86
-
87
- fs.appendFileSync(captureLog, `${turnHash}\n`);
88
-
89
- // Keep only last 100 hashes
90
- try {
91
- const hashes = fs.readFileSync(captureLog, 'utf8').split('\n').filter(Boolean);
92
- if (hashes.length > 100) {
93
- fs.writeFileSync(captureLog, hashes.slice(-100).join('\n') + '\n');
94
- }
95
- } catch {
96
- // Ignore cleanup errors
97
- }
98
- }
99
-
100
- // ═══════════════════════════════════════════════════════════════════════════
101
- // Lock Management
102
- // ═══════════════════════════════════════════════════════════════════════════
103
-
104
- function acquireLock(sessionId) {
105
- ensureStateDir();
106
- const lockFile = path.join(STATE_DIR, `lock-${sessionId}.lock`);
107
- const timeout = 5000; // 5 seconds
108
- const startTime = Date.now();
109
-
110
- while (fs.existsSync(lockFile)) {
111
- if (Date.now() - startTime > timeout) {
112
- // Check if lock is stale (older than 10 seconds)
113
- try {
114
- const stat = fs.statSync(lockFile);
115
- if (Date.now() - stat.mtimeMs > 10000) {
116
- fs.unlinkSync(lockFile);
117
- break;
118
- }
119
- } catch {
120
- break;
121
- }
122
- return false;
123
- }
124
- // Wait 100ms
125
- const waitUntil = Date.now() + 100;
126
- while (Date.now() < waitUntil) {}
127
- }
128
-
129
- fs.writeFileSync(lockFile, process.pid.toString());
130
- return true;
131
- }
132
-
133
- function releaseLock(sessionId) {
134
- const lockFile = path.join(STATE_DIR, `lock-${sessionId}.lock`);
135
-
136
- try {
137
- const content = fs.readFileSync(lockFile, 'utf8');
138
- if (content.trim() === process.pid.toString()) {
139
- fs.unlinkSync(lockFile);
140
- }
141
- } catch {
142
- // Lock file doesn't exist or can't be read
143
- }
144
- }
145
-
146
- // ═══════════════════════════════════════════════════════════════════════════
147
- // Cleanup
148
- // ═══════════════════════════════════════════════════════════════════════════
149
-
150
- function cleanupOldState() {
151
- if (!fs.existsSync(STATE_DIR)) return;
152
-
153
- const now = Date.now();
154
- const oneDayMs = 24 * 60 * 60 * 1000;
155
-
156
- try {
157
- const files = fs.readdirSync(STATE_DIR);
158
- for (const file of files) {
159
- const filePath = path.join(STATE_DIR, file);
160
- try {
161
- const stat = fs.statSync(filePath);
162
- if (now - stat.mtimeMs > oneDayMs) {
163
- fs.unlinkSync(filePath);
164
- }
165
- } catch {
166
- // Ignore file errors
167
- }
168
- }
169
- } catch {
170
- // Ignore directory errors
171
- }
172
- }
173
-
174
- module.exports = {
175
- PROJECT_ROOT,
176
- STATE_DIR,
177
- ensureStateDir,
178
- savePatterns,
179
- loadPatterns,
180
- clearPatterns,
181
- generateTurnHash,
182
- wasTurnCaptured,
183
- markTurnCaptured,
184
- acquireLock,
185
- releaseLock,
186
- cleanupOldState
187
- };