solvdex 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +274 -0
- package/dist/hooks/error-lookup.d.ts +4 -0
- package/dist/hooks/error-lookup.d.ts.map +1 -0
- package/dist/hooks/error-lookup.js +92 -0
- package/dist/hooks/error-lookup.js.map +1 -0
- package/dist/hooks/post-task.d.ts +15 -0
- package/dist/hooks/post-task.d.ts.map +1 -0
- package/dist/hooks/post-task.js +246 -0
- package/dist/hooks/post-task.js.map +1 -0
- package/dist/hooks/prompt-enrich.d.ts +16 -0
- package/dist/hooks/prompt-enrich.d.ts.map +1 -0
- package/dist/hooks/prompt-enrich.js +141 -0
- package/dist/hooks/prompt-enrich.js.map +1 -0
- package/dist/hooks/session-start-cli.d.ts +3 -0
- package/dist/hooks/session-start-cli.d.ts.map +1 -0
- package/dist/hooks/session-start-cli.js +81 -0
- package/dist/hooks/session-start-cli.js.map +1 -0
- package/dist/hooks/session-start.d.ts +4 -0
- package/dist/hooks/session-start.d.ts.map +1 -0
- package/dist/hooks/session-start.js +134 -0
- package/dist/hooks/session-start.js.map +1 -0
- package/dist/src/audit.d.ts +63 -0
- package/dist/src/audit.d.ts.map +1 -0
- package/dist/src/audit.js +229 -0
- package/dist/src/audit.js.map +1 -0
- package/dist/src/cache.d.ts +54 -0
- package/dist/src/cache.d.ts.map +1 -0
- package/dist/src/cache.js +167 -0
- package/dist/src/cache.js.map +1 -0
- package/dist/src/config.d.ts +52 -0
- package/dist/src/config.d.ts.map +1 -0
- package/dist/src/config.js +175 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/entry.d.ts +154 -0
- package/dist/src/entry.d.ts.map +1 -0
- package/dist/src/entry.js +469 -0
- package/dist/src/entry.js.map +1 -0
- package/dist/src/errors.d.ts +65 -0
- package/dist/src/errors.d.ts.map +1 -0
- package/dist/src/errors.js +121 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/frontmatter.d.ts +28 -0
- package/dist/src/frontmatter.d.ts.map +1 -0
- package/dist/src/frontmatter.js +111 -0
- package/dist/src/frontmatter.js.map +1 -0
- package/dist/src/index.d.ts +35 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +188 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/maturity.d.ts +31 -0
- package/dist/src/maturity.d.ts.map +1 -0
- package/dist/src/maturity.js +96 -0
- package/dist/src/maturity.js.map +1 -0
- package/dist/src/quality.d.ts +23 -0
- package/dist/src/quality.d.ts.map +1 -0
- package/dist/src/quality.js +236 -0
- package/dist/src/quality.js.map +1 -0
- package/dist/src/search.d.ts +35 -0
- package/dist/src/search.d.ts.map +1 -0
- package/dist/src/search.js +263 -0
- package/dist/src/search.js.map +1 -0
- package/dist/src/similarity.d.ts +42 -0
- package/dist/src/similarity.d.ts.map +1 -0
- package/dist/src/similarity.js +111 -0
- package/dist/src/similarity.js.map +1 -0
- package/dist/src/stats.d.ts +56 -0
- package/dist/src/stats.d.ts.map +1 -0
- package/dist/src/stats.js +198 -0
- package/dist/src/stats.js.map +1 -0
- package/dist/src/templates.d.ts +63 -0
- package/dist/src/templates.d.ts.map +1 -0
- package/dist/src/templates.js +347 -0
- package/dist/src/templates.js.map +1 -0
- package/dist/src/transfer.d.ts +92 -0
- package/dist/src/transfer.d.ts.map +1 -0
- package/dist/src/transfer.js +215 -0
- package/dist/src/transfer.js.map +1 -0
- package/dist/src/types.d.ts +270 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +153 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/validate.d.ts +90 -0
- package/dist/src/validate.d.ts.map +1 -0
- package/dist/src/validate.js +295 -0
- package/dist/src/validate.js.map +1 -0
- package/hooks/error-lookup.ts +110 -0
- package/hooks/hooks.json +49 -0
- package/hooks/post-task.ts +309 -0
- package/hooks/prompt-enrich.ts +162 -0
- package/hooks/session-start-cli.ts +96 -0
- package/hooks/session-start.ts +159 -0
- package/package.json +40 -0
- package/scripts/error-lookup.py +64 -0
- package/scripts/post-task.py +60 -0
- package/scripts/prompt-enrich.py +64 -0
- package/scripts/session-start.py +64 -0
- package/skills/wiki/SKILL.md +61 -0
- package/skills/wiki-add/SKILL.md +90 -0
- package/skills/wiki-browse/SKILL.md +108 -0
- package/skills/wiki-capture/SKILL.md +265 -0
- package/skills/wiki-explorer/SKILL.md +223 -0
- package/skills/wiki-export/SKILL.md +101 -0
- package/skills/wiki-fix/SKILL.md +86 -0
- package/skills/wiki-flag/SKILL.md +47 -0
- package/skills/wiki-import/SKILL.md +128 -0
- package/skills/wiki-init/SKILL.md +72 -0
- package/skills/wiki-scan/SKILL.md +98 -0
- package/skills/wiki-search/SKILL.md +86 -0
- package/skills/wiki-stats/SKILL.md +129 -0
- package/skills/wiki-status/SKILL.md +78 -0
- package/skills/wiki-test-trigger/SKILL.md +173 -0
- package/skills/wiki-validate/SKILL.md +62 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 duc.do
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
# Solvdex
|
|
2
|
+
|
|
3
|
+
[](./tests)
|
|
4
|
+
[](./package.json)
|
|
5
|
+
[](./LICENSE)
|
|
6
|
+
[](https://www.typescriptlang.org/)
|
|
7
|
+
|
|
8
|
+
> **An index of solved problems.** A Claude Code plugin that auto-captures and retrieves project knowledge.
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
12
|
+
│ Error: ETIMEDOUT connecting to database │
|
|
13
|
+
├─────────────────────────────────────────────────────────────┤
|
|
14
|
+
│ 📚 Solvdex found a solution: │
|
|
15
|
+
│ "Database Connection Timeout" │
|
|
16
|
+
│ Confidence: 85 │
|
|
17
|
+
│ │
|
|
18
|
+
│ Solution: Increase pool timeout in config... │
|
|
19
|
+
└─────────────────────────────────────────────────────────────┘
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Features
|
|
23
|
+
|
|
24
|
+
| Feature | Description |
|
|
25
|
+
|---------|-------------|
|
|
26
|
+
| 🔄 **Auto-Capture** | Saves solutions when errors are resolved |
|
|
27
|
+
| 🔍 **Auto-Lookup** | Surfaces relevant knowledge on errors |
|
|
28
|
+
| 📊 **7 Categories** | Organized knowledge across development domains |
|
|
29
|
+
| 🎯 **Trigger Patterns** | Regex matching for automatic error detection |
|
|
30
|
+
| 📈 **Confidence Tracking** | Trust scores with decay over time |
|
|
31
|
+
| 🔗 **Cross-References** | Link related entries and source files |
|
|
32
|
+
|
|
33
|
+
## Categories
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
.wiki/
|
|
37
|
+
├── issues/ # Bug fixes, error solutions
|
|
38
|
+
├── patterns/ # Reusable code patterns
|
|
39
|
+
├── gotchas/ # Pitfalls to avoid
|
|
40
|
+
├── testing/ # Test strategies, mocks
|
|
41
|
+
├── docs/ # Documentation guides
|
|
42
|
+
├── security/ # Auth, vulnerabilities
|
|
43
|
+
└── performance/ # Optimizations, benchmarks
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Quick Start
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# Initialize wiki
|
|
50
|
+
/wiki init
|
|
51
|
+
|
|
52
|
+
# Search for solutions
|
|
53
|
+
/wiki search "database timeout"
|
|
54
|
+
|
|
55
|
+
# Add current solution
|
|
56
|
+
/wiki add --category=issues
|
|
57
|
+
|
|
58
|
+
# Browse entries
|
|
59
|
+
/wiki browse
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Commands
|
|
63
|
+
|
|
64
|
+
### Core Commands
|
|
65
|
+
|
|
66
|
+
| Command | Description |
|
|
67
|
+
|---------|-------------|
|
|
68
|
+
| `/wiki init` | Create `.wiki/` structure |
|
|
69
|
+
| `/wiki add` | Save current solution |
|
|
70
|
+
| `/wiki search <query>` | Full-text search |
|
|
71
|
+
| `/wiki browse` | List entries with filters |
|
|
72
|
+
|
|
73
|
+
### Management Commands
|
|
74
|
+
|
|
75
|
+
| Command | Description |
|
|
76
|
+
|---------|-------------|
|
|
77
|
+
| `/wiki status` | Quick health overview |
|
|
78
|
+
| `/wiki stats` | Detailed analytics |
|
|
79
|
+
| `/wiki validate` | Check for issues |
|
|
80
|
+
| `/wiki scan` | Generate stubs from project |
|
|
81
|
+
| `/wiki flag <entry>` | Mark for review |
|
|
82
|
+
| `/wiki fix <entry>` | Update flagged entry |
|
|
83
|
+
|
|
84
|
+
### Transfer Commands
|
|
85
|
+
|
|
86
|
+
| Command | Description |
|
|
87
|
+
|---------|-------------|
|
|
88
|
+
| `/wiki export [file]` | Export to JSON |
|
|
89
|
+
| `/wiki import <file>` | Import from JSON |
|
|
90
|
+
| `/wiki test-trigger` | Test regex patterns |
|
|
91
|
+
|
|
92
|
+
### Agents
|
|
93
|
+
|
|
94
|
+
| Command | Description |
|
|
95
|
+
|---------|-------------|
|
|
96
|
+
| `/wiki explore <query>` | Deep multi-strategy search |
|
|
97
|
+
| `/wiki capture` | Extract knowledge from conversation |
|
|
98
|
+
|
|
99
|
+
## How It Works
|
|
100
|
+
|
|
101
|
+
### Automatic Knowledge Capture
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
|
105
|
+
│ You solve │────▶│ Solvdex │────▶│ .wiki/ │
|
|
106
|
+
│ an error │ │ detects │ │ saved! │
|
|
107
|
+
└──────────────┘ └──────────────┘ └──────────────┘
|
|
108
|
+
|
|
109
|
+
Signals detected:
|
|
110
|
+
• error_resolved → issues/
|
|
111
|
+
• workaround → gotchas/
|
|
112
|
+
• user confirms → auto-detect category
|
|
113
|
+
• explicit save → "remember this"
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Automatic Knowledge Retrieval
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
|
120
|
+
│ Error │────▶│ Solvdex │────▶│ Solution │
|
|
121
|
+
│ occurs │ │ matches │ │ displayed │
|
|
122
|
+
└──────────────┘ └──────────────┘ └──────────────┘
|
|
123
|
+
|
|
124
|
+
Lookup triggers:
|
|
125
|
+
• Session start → relevant context
|
|
126
|
+
• Error match → trigger patterns
|
|
127
|
+
• Prompt keywords → category detection
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Entry Format
|
|
131
|
+
|
|
132
|
+
```yaml
|
|
133
|
+
---
|
|
134
|
+
title: Database Connection Timeout
|
|
135
|
+
created: 2025-01-20
|
|
136
|
+
status: active
|
|
137
|
+
confidence: 85
|
|
138
|
+
tags: [database, timeout, postgres]
|
|
139
|
+
trigger: "ETIMEDOUT.*postgres"
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Problem
|
|
143
|
+
Connection times out after 30 seconds...
|
|
144
|
+
|
|
145
|
+
## Solution
|
|
146
|
+
Increase timeout and add connection pool...
|
|
147
|
+
|
|
148
|
+
## Related
|
|
149
|
+
- [[issues/connection-pool]]
|
|
150
|
+
- `src/db/config.ts:45`
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
> **Note:** Entries also include maturity tracking fields (`maturity`, `use_count`, `last_used`). See [Entry Maturity System](#entry-maturity-system) below.
|
|
154
|
+
|
|
155
|
+
### Entry Maturity System
|
|
156
|
+
|
|
157
|
+
Solvdex automatically tracks and promotes entries through maturity phases based on usage:
|
|
158
|
+
|
|
159
|
+
| Maturity | Criteria | Confidence | Meaning |
|
|
160
|
+
|----------|----------|------------|---------|
|
|
161
|
+
| **captured** | 0-2 uses | 40 | Newly documented, unverified |
|
|
162
|
+
| **verified** | 3+ uses | 70 | Proven to work multiple times |
|
|
163
|
+
| **validated** | 10+ uses, 30+ days old | 90 | Battle-tested over time |
|
|
164
|
+
|
|
165
|
+
**Automatic Promotion:**
|
|
166
|
+
- Entries start as `captured` when created
|
|
167
|
+
- Maturity is evaluated automatically each time `recordEntryUsage()` is called
|
|
168
|
+
- After 3 successful uses → promoted to `verified`
|
|
169
|
+
- After 10 uses AND 30+ days → promoted to `validated`
|
|
170
|
+
- Confidence scores update automatically with maturity
|
|
171
|
+
|
|
172
|
+
**Safety Features:**
|
|
173
|
+
- Flagged entries freeze maturity progression
|
|
174
|
+
- Manual maturity overrides are respected
|
|
175
|
+
- Maturity only goes up (no demotion)
|
|
176
|
+
- All promotions logged in audit trail
|
|
177
|
+
|
|
178
|
+
**Example Entry:**
|
|
179
|
+
```yaml
|
|
180
|
+
---
|
|
181
|
+
title: Fix Redis Connection Timeout
|
|
182
|
+
maturity: verified
|
|
183
|
+
confidence: 70
|
|
184
|
+
use_count: 5
|
|
185
|
+
last_used: 2025-01-23
|
|
186
|
+
audit:
|
|
187
|
+
- date: 2025-01-20
|
|
188
|
+
action: created
|
|
189
|
+
by: user
|
|
190
|
+
- date: 2025-01-22
|
|
191
|
+
action: maturity_promoted
|
|
192
|
+
by: system
|
|
193
|
+
context: "Auto-promoted: captured → verified (3 uses)"
|
|
194
|
+
---
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Confidence Scale
|
|
198
|
+
|
|
199
|
+
| Score | Level | Meaning |
|
|
200
|
+
|-------|-------|---------|
|
|
201
|
+
| 90-100 | 🟢 High | Typically validated entries |
|
|
202
|
+
| 60-89 | 🟡 Medium | Typically verified entries or manually set |
|
|
203
|
+
| 0-59 | 🔴 Low | Typically captured entries or stubs |
|
|
204
|
+
|
|
205
|
+
Confidence auto-decays for entries unused for 90+ days.
|
|
206
|
+
|
|
207
|
+
## Hooks
|
|
208
|
+
|
|
209
|
+
Real-time integration with Claude Code:
|
|
210
|
+
|
|
211
|
+
| Hook | When | Action |
|
|
212
|
+
|------|------|--------|
|
|
213
|
+
| `SessionStart` | New conversation | Surface relevant entries |
|
|
214
|
+
| `UserPromptSubmit` | Each prompt | Enrich with context |
|
|
215
|
+
| `PostToolUseFailure` | Error occurs | Show matching solutions |
|
|
216
|
+
| `Stop` | Task completes | Offer to capture knowledge |
|
|
217
|
+
|
|
218
|
+
## Installation
|
|
219
|
+
|
|
220
|
+
### From Source
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
git clone https://github.com/ducdmdev/solvdex.git
|
|
224
|
+
cd solvdex
|
|
225
|
+
npm install
|
|
226
|
+
npm run build
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Via Claude Code Marketplace
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
# Coming soon
|
|
233
|
+
/plugin install solvdex
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## Documentation
|
|
237
|
+
|
|
238
|
+
| Document | Description |
|
|
239
|
+
|----------|-------------|
|
|
240
|
+
| [Getting Started](./docs/getting-started.md) | Quick setup guide |
|
|
241
|
+
| [Architecture](./docs/architecture.md) | System design |
|
|
242
|
+
| [Workflows](./docs/workflows.md) | Hook and skill flows |
|
|
243
|
+
| [Use Cases](./docs/use-cases.md) | Common scenarios |
|
|
244
|
+
|
|
245
|
+
## Development
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
npm install # Install dependencies
|
|
249
|
+
npm run build # Compile TypeScript
|
|
250
|
+
npm test # Run 204 tests
|
|
251
|
+
npm run lint # Check code style
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Project Structure
|
|
255
|
+
|
|
256
|
+
```
|
|
257
|
+
solvdex/
|
|
258
|
+
├── src/ # Core TypeScript library
|
|
259
|
+
├── skills/ # 16 Claude Code skills
|
|
260
|
+
├── hooks/ # 4 automated hooks
|
|
261
|
+
├── docs/ # Documentation
|
|
262
|
+
└── tests/ # Test suite (204 tests)
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## License
|
|
266
|
+
|
|
267
|
+
MIT © [duc.do](https://github.com/ducdmdev)
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
<p align="center">
|
|
272
|
+
<b>Stop re-solving the same problems.</b><br>
|
|
273
|
+
<i>Build your knowledge index with Solvdex.</i>
|
|
274
|
+
</p>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-lookup.d.ts","sourceRoot":"","sources":["../../hooks/error-lookup.ts"],"names":[],"mappings":"AACA,OAAO,EAML,iBAAiB,EAKlB,MAAM,iBAAiB,CAAC;AAezB,wBAAsB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAwErF;AAUD,eAAe,aAAa,CAAC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.onErrorLookup = onErrorLookup;
|
|
4
|
+
// hooks/error-lookup.ts
|
|
5
|
+
const index_js_1 = require("../src/index.js");
|
|
6
|
+
/**
|
|
7
|
+
* Extracts the solution section from wiki entry content.
|
|
8
|
+
*/
|
|
9
|
+
function extractSolution(content) {
|
|
10
|
+
// Look for Solution heading
|
|
11
|
+
const solutionMatch = content.match(/## Solution\n([\s\S]*?)(?=\n## |$)/);
|
|
12
|
+
if (solutionMatch) {
|
|
13
|
+
return solutionMatch[1].trim().slice(0, 200) + '...';
|
|
14
|
+
}
|
|
15
|
+
// Fallback: first 200 chars
|
|
16
|
+
return content.slice(0, 200) + '...';
|
|
17
|
+
}
|
|
18
|
+
async function onErrorLookup(input) {
|
|
19
|
+
try {
|
|
20
|
+
// Validate input first
|
|
21
|
+
const validatedInput = (0, index_js_1.validateErrorLookupInput)(input);
|
|
22
|
+
const { projectRoot, errorText, toolResult } = validatedInput;
|
|
23
|
+
// Get error text from either direct input or tool stderr
|
|
24
|
+
const error = errorText || toolResult?.stderr || '';
|
|
25
|
+
if (!error || !(0, index_js_1.wikiExists)(projectRoot)) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
// Try to match error against trigger patterns
|
|
29
|
+
const results = await (0, index_js_1.matchTrigger)(projectRoot, error);
|
|
30
|
+
const bestMatch = (0, index_js_1.getBestMatch)(results);
|
|
31
|
+
if (bestMatch && bestMatch.entry.frontmatter.confidence >= index_js_1.CONFIDENCE.THRESHOLD) {
|
|
32
|
+
// Record usage for analytics
|
|
33
|
+
try {
|
|
34
|
+
const { recordEntryUsage } = await import('../src/index.js');
|
|
35
|
+
recordEntryUsage(projectRoot, bestMatch.entry.path);
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// Usage tracking failure is non-critical
|
|
39
|
+
}
|
|
40
|
+
// Output for Claude Code hook integration (user-facing console logs)
|
|
41
|
+
console.log(`📚 Solvdex found a solution:`);
|
|
42
|
+
console.log(` "${bestMatch.entry.frontmatter.title}"`);
|
|
43
|
+
console.log(` Confidence: ${bestMatch.entry.frontmatter.confidence}`);
|
|
44
|
+
console.log(` `);
|
|
45
|
+
console.log(` Solution: ${extractSolution(bestMatch.entry.content)}`);
|
|
46
|
+
// Structured output for Claude Code (includes both old and new format for backward compatibility)
|
|
47
|
+
const output = {
|
|
48
|
+
// Old format (for backward compatibility)
|
|
49
|
+
type: 'wiki_solution',
|
|
50
|
+
message: `Wiki: Found "${bestMatch.entry.frontmatter.title}" (confidence: ${bestMatch.entry.frontmatter.confidence})`,
|
|
51
|
+
entry: bestMatch.entry,
|
|
52
|
+
// New format (Claude Code integration)
|
|
53
|
+
continue: true,
|
|
54
|
+
hookSpecificOutput: {
|
|
55
|
+
type: 'solution_found',
|
|
56
|
+
message: `Found solution: "${bestMatch.entry.frontmatter.title}"`,
|
|
57
|
+
entries: [{
|
|
58
|
+
title: bestMatch.entry.frontmatter.title,
|
|
59
|
+
category: bestMatch.entry.category,
|
|
60
|
+
path: bestMatch.entry.path,
|
|
61
|
+
confidence: bestMatch.entry.frontmatter.confidence
|
|
62
|
+
}]
|
|
63
|
+
},
|
|
64
|
+
additionalContext: formatSolutionForContext(bestMatch)
|
|
65
|
+
};
|
|
66
|
+
// Output JSON marker + JSON (MUST be last output)
|
|
67
|
+
console.log('\n__HOOK_OUTPUT__');
|
|
68
|
+
console.log(JSON.stringify(output));
|
|
69
|
+
return output;
|
|
70
|
+
}
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
// Handle validation errors separately
|
|
75
|
+
if (error instanceof index_js_1.ValidationError) {
|
|
76
|
+
console.error(`[Solvdex] Invalid input: ${error.message}`);
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
// Graceful degradation - log error but don't crash
|
|
80
|
+
console.error(`[Solvdex] Error in error-lookup hook: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Formats a solution match into a readable context string for Claude Code.
|
|
86
|
+
*/
|
|
87
|
+
function formatSolutionForContext(match) {
|
|
88
|
+
const e = match.entry;
|
|
89
|
+
return `## ${e.frontmatter.title} (${e.category})\nConfidence: ${e.frontmatter.confidence}\n\n${e.content}`;
|
|
90
|
+
}
|
|
91
|
+
exports.default = onErrorLookup;
|
|
92
|
+
//# sourceMappingURL=error-lookup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-lookup.js","sourceRoot":"","sources":["../../hooks/error-lookup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { PostTaskOutput } from '../src/index.js';
|
|
2
|
+
interface TaskContext {
|
|
3
|
+
projectRoot: string;
|
|
4
|
+
taskDescription: string;
|
|
5
|
+
outcome: 'success' | 'failure';
|
|
6
|
+
errorEncountered?: string;
|
|
7
|
+
errorResolved?: boolean;
|
|
8
|
+
filesModified?: string[];
|
|
9
|
+
userConfirmation?: string;
|
|
10
|
+
codeChanges?: string;
|
|
11
|
+
actionHistory?: string[];
|
|
12
|
+
}
|
|
13
|
+
export declare function onPostTask(context: TaskContext): Promise<PostTaskOutput | null>;
|
|
14
|
+
export default onPostTask;
|
|
15
|
+
//# sourceMappingURL=post-task.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"post-task.d.ts","sourceRoot":"","sources":["../../hooks/post-task.ts"],"names":[],"mappings":"AACA,OAAO,EAML,cAAc,EACf,MAAM,iBAAiB,CAAC;AAEzB,UAAU,WAAW;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,SAAS,GAAG,SAAS,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAWD,wBAAsB,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAmFrF;AAkMD,eAAe,UAAU,CAAC"}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.onPostTask = onPostTask;
|
|
4
|
+
// hooks/post-task.ts
|
|
5
|
+
const index_js_1 = require("../src/index.js");
|
|
6
|
+
// Default enabled signals (can be overridden by future config)
|
|
7
|
+
const DEFAULT_SIGNALS = [
|
|
8
|
+
'error_resolved',
|
|
9
|
+
'user_confirmation',
|
|
10
|
+
'explicit_save',
|
|
11
|
+
'repeated_pattern',
|
|
12
|
+
'workaround_applied'
|
|
13
|
+
];
|
|
14
|
+
async function onPostTask(context) {
|
|
15
|
+
try {
|
|
16
|
+
const { projectRoot } = context;
|
|
17
|
+
if (!(0, index_js_1.wikiExists)(projectRoot)) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
// Check signals
|
|
21
|
+
const signal = detectSignal(context, DEFAULT_SIGNALS);
|
|
22
|
+
if (!signal) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
// Extract entry details
|
|
26
|
+
const entryDetails = extractEntryDetails(context, signal);
|
|
27
|
+
// Check for duplicates before creating (but don't block on it)
|
|
28
|
+
let isDuplicate = false;
|
|
29
|
+
try {
|
|
30
|
+
const { checkDuplicate } = await import('../src/index.js');
|
|
31
|
+
const dupCheck = await checkDuplicate(projectRoot, entryDetails.title, entryDetails.tags, entryDetails.category);
|
|
32
|
+
isDuplicate = dupCheck.isDuplicate;
|
|
33
|
+
if (isDuplicate) {
|
|
34
|
+
console.log(`📚 Solvdex: Skipping duplicate "${entryDetails.title}"`);
|
|
35
|
+
console.log(` Similar to: "${dupCheck.matchedEntry?.frontmatter.title}"`);
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
// Duplicate check failure is non-critical, proceed with creation
|
|
41
|
+
}
|
|
42
|
+
// Create entry
|
|
43
|
+
const entry = (0, index_js_1.createEntry)(projectRoot, {
|
|
44
|
+
category: entryDetails.category,
|
|
45
|
+
title: entryDetails.title,
|
|
46
|
+
tags: entryDetails.tags,
|
|
47
|
+
content: entryDetails.content,
|
|
48
|
+
trigger: entryDetails.trigger,
|
|
49
|
+
autoCapture: true,
|
|
50
|
+
stub: true,
|
|
51
|
+
source: `auto-capture:${signal}`
|
|
52
|
+
});
|
|
53
|
+
// Output for Claude Code Stop hook integration (user-facing console logs)
|
|
54
|
+
console.log(`📚 Solvdex: Captured "${entry.frontmatter.title}"`);
|
|
55
|
+
console.log(` Category: ${entry.category}`);
|
|
56
|
+
console.log(` Signal: ${signal}`);
|
|
57
|
+
// Structured output for Claude Code (includes both old and new format for backward compatibility)
|
|
58
|
+
const output = {
|
|
59
|
+
// Old format (for backward compatibility)
|
|
60
|
+
type: 'wiki_captured',
|
|
61
|
+
message: `Wiki: Saved "${entry.frontmatter.title}" to ${entry.category}/`,
|
|
62
|
+
entry,
|
|
63
|
+
signal,
|
|
64
|
+
// New format (Claude Code integration)
|
|
65
|
+
continue: true,
|
|
66
|
+
hookSpecificOutput: {
|
|
67
|
+
type: 'entry_captured',
|
|
68
|
+
message: `Captured "${entry.frontmatter.title}" to ${entry.category}/`,
|
|
69
|
+
entryPath: entry.path
|
|
70
|
+
},
|
|
71
|
+
additionalContext: formatEntryForContext(entry, signal)
|
|
72
|
+
};
|
|
73
|
+
// Output JSON marker + JSON (MUST be last output)
|
|
74
|
+
console.log('\n__HOOK_OUTPUT__');
|
|
75
|
+
console.log(JSON.stringify(output));
|
|
76
|
+
return output;
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
// Graceful degradation - log error but don't crash
|
|
80
|
+
console.error(`[Solvdex] Error in post-task hook: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Detects if similar actions have been performed 3+ times.
|
|
86
|
+
* Returns the repeated action if found.
|
|
87
|
+
*/
|
|
88
|
+
function detectRepeatedPattern(actionHistory) {
|
|
89
|
+
if (!actionHistory || actionHistory.length < 3) {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
// Count occurrences of each action
|
|
93
|
+
const counts = {};
|
|
94
|
+
for (const action of actionHistory) {
|
|
95
|
+
const normalized = action.toLowerCase().trim();
|
|
96
|
+
counts[normalized] = (counts[normalized] || 0) + 1;
|
|
97
|
+
}
|
|
98
|
+
// Find action repeated 3+ times
|
|
99
|
+
for (const [action, count] of Object.entries(counts)) {
|
|
100
|
+
if (count >= 3) {
|
|
101
|
+
return action;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
function detectSignal(context, enabledSignals) {
|
|
107
|
+
// Signal 1: Error resolved
|
|
108
|
+
if (enabledSignals.includes('error_resolved') &&
|
|
109
|
+
context.errorEncountered &&
|
|
110
|
+
context.errorResolved &&
|
|
111
|
+
context.outcome === 'success') {
|
|
112
|
+
return 'error_resolved';
|
|
113
|
+
}
|
|
114
|
+
// Signal 2: User confirmation
|
|
115
|
+
if (enabledSignals.includes('user_confirmation') &&
|
|
116
|
+
context.userConfirmation &&
|
|
117
|
+
isPositiveConfirmation(context.userConfirmation)) {
|
|
118
|
+
return 'user_confirmation';
|
|
119
|
+
}
|
|
120
|
+
// Signal 3: Explicit save request
|
|
121
|
+
if (enabledSignals.includes('explicit_save') &&
|
|
122
|
+
context.userConfirmation &&
|
|
123
|
+
isExplicitSaveRequest(context.userConfirmation)) {
|
|
124
|
+
return 'explicit_save';
|
|
125
|
+
}
|
|
126
|
+
// Signal 4: Repeated pattern
|
|
127
|
+
if (enabledSignals.includes('repeated_pattern') && context.actionHistory) {
|
|
128
|
+
const repeatedAction = detectRepeatedPattern(context.actionHistory);
|
|
129
|
+
if (repeatedAction) {
|
|
130
|
+
return 'repeated_pattern';
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// Signal 5: Workaround applied (detect HACK/WORKAROUND comments)
|
|
134
|
+
if (enabledSignals.includes('workaround_applied') &&
|
|
135
|
+
context.codeChanges &&
|
|
136
|
+
hasWorkaroundMarkers(context.codeChanges)) {
|
|
137
|
+
return 'workaround_applied';
|
|
138
|
+
}
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
function isPositiveConfirmation(text) {
|
|
142
|
+
const positivePatterns = [
|
|
143
|
+
'that fixed it',
|
|
144
|
+
'works now',
|
|
145
|
+
'perfect',
|
|
146
|
+
'that worked',
|
|
147
|
+
'thank you',
|
|
148
|
+
'great',
|
|
149
|
+
'awesome',
|
|
150
|
+
'solved'
|
|
151
|
+
];
|
|
152
|
+
const textLower = text.toLowerCase();
|
|
153
|
+
return positivePatterns.some(p => textLower.includes(p));
|
|
154
|
+
}
|
|
155
|
+
function isExplicitSaveRequest(text) {
|
|
156
|
+
const savePatterns = [
|
|
157
|
+
'save this to wiki',
|
|
158
|
+
'remember this',
|
|
159
|
+
'add to wiki',
|
|
160
|
+
'wiki this',
|
|
161
|
+
'document this'
|
|
162
|
+
];
|
|
163
|
+
const textLower = text.toLowerCase();
|
|
164
|
+
return savePatterns.some(p => textLower.includes(p));
|
|
165
|
+
}
|
|
166
|
+
function hasWorkaroundMarkers(codeChanges) {
|
|
167
|
+
const workaroundPatterns = [
|
|
168
|
+
/\/\/\s*(HACK|WORKAROUND|TODO|FIXME):/i,
|
|
169
|
+
/\/\*\s*(HACK|WORKAROUND|TODO|FIXME):/i,
|
|
170
|
+
/#\s*(HACK|WORKAROUND|TODO|FIXME):/i
|
|
171
|
+
];
|
|
172
|
+
return workaroundPatterns.some(pattern => pattern.test(codeChanges));
|
|
173
|
+
}
|
|
174
|
+
function extractEntryDetails(context, signal) {
|
|
175
|
+
// Determine category based on signal and task keywords (7 categories)
|
|
176
|
+
let category = 'issues'; // default
|
|
177
|
+
if (signal === 'error_resolved') {
|
|
178
|
+
category = 'issues';
|
|
179
|
+
}
|
|
180
|
+
else if (signal === 'workaround_applied') {
|
|
181
|
+
category = 'gotchas';
|
|
182
|
+
}
|
|
183
|
+
else if (signal === 'repeated_pattern') {
|
|
184
|
+
category = 'patterns';
|
|
185
|
+
}
|
|
186
|
+
else if (context.taskDescription) {
|
|
187
|
+
const task = context.taskDescription.toLowerCase();
|
|
188
|
+
// Testing signals
|
|
189
|
+
if (task.includes('test') || task.includes('mock') || task.includes('fixture')) {
|
|
190
|
+
category = 'testing';
|
|
191
|
+
}
|
|
192
|
+
// Documentation signals
|
|
193
|
+
else if (task.includes('document') || task.includes('readme') || task.includes('guide')) {
|
|
194
|
+
category = 'docs';
|
|
195
|
+
}
|
|
196
|
+
// Security signals
|
|
197
|
+
else if (task.includes('auth') || task.includes('security') || task.includes('permission')) {
|
|
198
|
+
category = 'security';
|
|
199
|
+
}
|
|
200
|
+
// Performance signals
|
|
201
|
+
else if (task.includes('slow') || task.includes('optimize') || task.includes('performance')) {
|
|
202
|
+
category = 'performance';
|
|
203
|
+
}
|
|
204
|
+
// Pattern signals
|
|
205
|
+
else if (task.includes('pattern') || task.includes('reusable')) {
|
|
206
|
+
category = 'patterns';
|
|
207
|
+
}
|
|
208
|
+
// Gotcha signals
|
|
209
|
+
else if (task.includes('careful') || task.includes('avoid') || task.includes('pitfall')) {
|
|
210
|
+
category = 'gotchas';
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
// Generate title from task or error
|
|
214
|
+
const title = context.errorEncountered
|
|
215
|
+
? `Fix: ${context.errorEncountered.substring(0, 50)}`
|
|
216
|
+
: context.taskDescription?.substring(0, 50) || 'Auto-captured entry';
|
|
217
|
+
// Extract tags from context
|
|
218
|
+
const tags = [];
|
|
219
|
+
if (context.filesModified) {
|
|
220
|
+
// Add file extension tags
|
|
221
|
+
const extensions = new Set(context.filesModified
|
|
222
|
+
.map(f => f.split('.').pop())
|
|
223
|
+
.filter(Boolean));
|
|
224
|
+
tags.push(...Array.from(extensions));
|
|
225
|
+
}
|
|
226
|
+
if (signal) {
|
|
227
|
+
tags.push(`auto:${signal}`);
|
|
228
|
+
}
|
|
229
|
+
// Generate stub content
|
|
230
|
+
const stubContent = (0, index_js_1.generateStubContent)(category);
|
|
231
|
+
return {
|
|
232
|
+
category,
|
|
233
|
+
title: title.replace(/[^\w\s-]/g, '').trim(),
|
|
234
|
+
tags,
|
|
235
|
+
content: stubContent,
|
|
236
|
+
trigger: context.errorEncountered
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Formats a captured entry into a readable context string for Claude Code.
|
|
241
|
+
*/
|
|
242
|
+
function formatEntryForContext(entry, signal) {
|
|
243
|
+
return `## Captured Entry: ${entry.frontmatter.title}\nCategory: ${entry.category}\nSignal: ${signal}\nPath: ${entry.path}\n\n${entry.content.substring(0, 300)}...`;
|
|
244
|
+
}
|
|
245
|
+
exports.default = onPostTask;
|
|
246
|
+
//# sourceMappingURL=post-task.js.map
|