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.
Files changed (113) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +274 -0
  3. package/dist/hooks/error-lookup.d.ts +4 -0
  4. package/dist/hooks/error-lookup.d.ts.map +1 -0
  5. package/dist/hooks/error-lookup.js +92 -0
  6. package/dist/hooks/error-lookup.js.map +1 -0
  7. package/dist/hooks/post-task.d.ts +15 -0
  8. package/dist/hooks/post-task.d.ts.map +1 -0
  9. package/dist/hooks/post-task.js +246 -0
  10. package/dist/hooks/post-task.js.map +1 -0
  11. package/dist/hooks/prompt-enrich.d.ts +16 -0
  12. package/dist/hooks/prompt-enrich.d.ts.map +1 -0
  13. package/dist/hooks/prompt-enrich.js +141 -0
  14. package/dist/hooks/prompt-enrich.js.map +1 -0
  15. package/dist/hooks/session-start-cli.d.ts +3 -0
  16. package/dist/hooks/session-start-cli.d.ts.map +1 -0
  17. package/dist/hooks/session-start-cli.js +81 -0
  18. package/dist/hooks/session-start-cli.js.map +1 -0
  19. package/dist/hooks/session-start.d.ts +4 -0
  20. package/dist/hooks/session-start.d.ts.map +1 -0
  21. package/dist/hooks/session-start.js +134 -0
  22. package/dist/hooks/session-start.js.map +1 -0
  23. package/dist/src/audit.d.ts +63 -0
  24. package/dist/src/audit.d.ts.map +1 -0
  25. package/dist/src/audit.js +229 -0
  26. package/dist/src/audit.js.map +1 -0
  27. package/dist/src/cache.d.ts +54 -0
  28. package/dist/src/cache.d.ts.map +1 -0
  29. package/dist/src/cache.js +167 -0
  30. package/dist/src/cache.js.map +1 -0
  31. package/dist/src/config.d.ts +52 -0
  32. package/dist/src/config.d.ts.map +1 -0
  33. package/dist/src/config.js +175 -0
  34. package/dist/src/config.js.map +1 -0
  35. package/dist/src/entry.d.ts +154 -0
  36. package/dist/src/entry.d.ts.map +1 -0
  37. package/dist/src/entry.js +469 -0
  38. package/dist/src/entry.js.map +1 -0
  39. package/dist/src/errors.d.ts +65 -0
  40. package/dist/src/errors.d.ts.map +1 -0
  41. package/dist/src/errors.js +121 -0
  42. package/dist/src/errors.js.map +1 -0
  43. package/dist/src/frontmatter.d.ts +28 -0
  44. package/dist/src/frontmatter.d.ts.map +1 -0
  45. package/dist/src/frontmatter.js +111 -0
  46. package/dist/src/frontmatter.js.map +1 -0
  47. package/dist/src/index.d.ts +35 -0
  48. package/dist/src/index.d.ts.map +1 -0
  49. package/dist/src/index.js +188 -0
  50. package/dist/src/index.js.map +1 -0
  51. package/dist/src/maturity.d.ts +31 -0
  52. package/dist/src/maturity.d.ts.map +1 -0
  53. package/dist/src/maturity.js +96 -0
  54. package/dist/src/maturity.js.map +1 -0
  55. package/dist/src/quality.d.ts +23 -0
  56. package/dist/src/quality.d.ts.map +1 -0
  57. package/dist/src/quality.js +236 -0
  58. package/dist/src/quality.js.map +1 -0
  59. package/dist/src/search.d.ts +35 -0
  60. package/dist/src/search.d.ts.map +1 -0
  61. package/dist/src/search.js +263 -0
  62. package/dist/src/search.js.map +1 -0
  63. package/dist/src/similarity.d.ts +42 -0
  64. package/dist/src/similarity.d.ts.map +1 -0
  65. package/dist/src/similarity.js +111 -0
  66. package/dist/src/similarity.js.map +1 -0
  67. package/dist/src/stats.d.ts +56 -0
  68. package/dist/src/stats.d.ts.map +1 -0
  69. package/dist/src/stats.js +198 -0
  70. package/dist/src/stats.js.map +1 -0
  71. package/dist/src/templates.d.ts +63 -0
  72. package/dist/src/templates.d.ts.map +1 -0
  73. package/dist/src/templates.js +347 -0
  74. package/dist/src/templates.js.map +1 -0
  75. package/dist/src/transfer.d.ts +92 -0
  76. package/dist/src/transfer.d.ts.map +1 -0
  77. package/dist/src/transfer.js +215 -0
  78. package/dist/src/transfer.js.map +1 -0
  79. package/dist/src/types.d.ts +270 -0
  80. package/dist/src/types.d.ts.map +1 -0
  81. package/dist/src/types.js +153 -0
  82. package/dist/src/types.js.map +1 -0
  83. package/dist/src/validate.d.ts +90 -0
  84. package/dist/src/validate.d.ts.map +1 -0
  85. package/dist/src/validate.js +295 -0
  86. package/dist/src/validate.js.map +1 -0
  87. package/hooks/error-lookup.ts +110 -0
  88. package/hooks/hooks.json +49 -0
  89. package/hooks/post-task.ts +309 -0
  90. package/hooks/prompt-enrich.ts +162 -0
  91. package/hooks/session-start-cli.ts +96 -0
  92. package/hooks/session-start.ts +159 -0
  93. package/package.json +40 -0
  94. package/scripts/error-lookup.py +64 -0
  95. package/scripts/post-task.py +60 -0
  96. package/scripts/prompt-enrich.py +64 -0
  97. package/scripts/session-start.py +64 -0
  98. package/skills/wiki/SKILL.md +61 -0
  99. package/skills/wiki-add/SKILL.md +90 -0
  100. package/skills/wiki-browse/SKILL.md +108 -0
  101. package/skills/wiki-capture/SKILL.md +265 -0
  102. package/skills/wiki-explorer/SKILL.md +223 -0
  103. package/skills/wiki-export/SKILL.md +101 -0
  104. package/skills/wiki-fix/SKILL.md +86 -0
  105. package/skills/wiki-flag/SKILL.md +47 -0
  106. package/skills/wiki-import/SKILL.md +128 -0
  107. package/skills/wiki-init/SKILL.md +72 -0
  108. package/skills/wiki-scan/SKILL.md +98 -0
  109. package/skills/wiki-search/SKILL.md +86 -0
  110. package/skills/wiki-stats/SKILL.md +129 -0
  111. package/skills/wiki-status/SKILL.md +78 -0
  112. package/skills/wiki-test-trigger/SKILL.md +173 -0
  113. package/skills/wiki-validate/SKILL.md +62 -0
@@ -0,0 +1,159 @@
1
+ // hooks/session-start.ts
2
+ import {
3
+ wikiExists,
4
+ searchWiki,
5
+ DEFAULT_CATEGORIES,
6
+ SessionStartOutput,
7
+ SearchResult,
8
+ validateSessionStartInput,
9
+ ValidationError,
10
+ SessionStartContext
11
+ } from '../src/index.js';
12
+
13
+ const CATEGORY_KEYWORDS: Record<string, string[]> = {
14
+ issues: ['error', 'fix', 'bug', 'broken', 'fails', 'crash', 'exception', 'trouble'],
15
+ patterns: ['pattern', 'template', 'reusable', 'design', 'approach', 'best practice'],
16
+ gotchas: ['careful', 'watch out', 'pitfall', 'gotcha', 'trap', 'avoid', 'never'],
17
+ testing: ['test', 'mock', 'fixture', 'assert', 'spec', 'coverage', 'jest', 'vitest'],
18
+ docs: ['document', 'readme', 'guide', 'tutorial', 'api docs', 'documentation'],
19
+ security: ['auth', 'token', 'vulnerability', 'permission', 'csrf', 'xss', 'injection', 'security'],
20
+ performance: ['slow', 'optimize', 'memory', 'latency', 'benchmark', 'profiling', 'performance']
21
+ };
22
+
23
+ const CATEGORY_PATH_HINTS: Record<string, string[]> = {
24
+ testing: ['test', 'spec', 'fixture', 'mock', '__tests__'],
25
+ docs: ['doc', 'readme', 'wiki', 'guide', 'docs'],
26
+ security: ['auth', 'secret', 'cred', 'permission', 'security'],
27
+ performance: ['perf', 'bench', 'profile', 'optim']
28
+ };
29
+
30
+ function detectCategoryFromPaths(paths: string[]): string[] {
31
+ const detected: Set<string> = new Set();
32
+
33
+ for (const filePath of paths) {
34
+ const pathLower = filePath.toLowerCase();
35
+ for (const [category, hints] of Object.entries(CATEGORY_PATH_HINTS)) {
36
+ if (hints.some(hint => pathLower.includes(hint))) {
37
+ detected.add(category);
38
+ }
39
+ }
40
+ }
41
+
42
+ return Array.from(detected);
43
+ }
44
+
45
+ export async function onSessionStart(context: unknown): Promise<SessionStartOutput | null> {
46
+ try {
47
+ // Validate input first
48
+ const validatedContext = validateSessionStartInput(context);
49
+ const { projectRoot, taskDescription, filePaths } = validatedContext;
50
+
51
+ if (!wikiExists(projectRoot)) {
52
+ return null;
53
+ }
54
+
55
+ if (!taskDescription) {
56
+ return null;
57
+ }
58
+
59
+ // Check which categories might be relevant based on keywords
60
+ const relevantCategories: string[] = [];
61
+ for (const category of DEFAULT_CATEGORIES) {
62
+ if (isRelevantCategory(taskDescription, category)) {
63
+ relevantCategories.push(category);
64
+ }
65
+ }
66
+
67
+ // Also check paths for category hints
68
+ if (filePaths && filePaths.length > 0) {
69
+ const pathCategories = detectCategoryFromPaths(filePaths);
70
+ for (const cat of pathCategories) {
71
+ if (!relevantCategories.includes(cat)) {
72
+ relevantCategories.push(cat);
73
+ }
74
+ }
75
+ }
76
+
77
+ // Search wiki for relevant entries
78
+ const searchResults = await searchWiki(projectRoot, { query: taskDescription });
79
+
80
+ if (searchResults.length > 0 || relevantCategories.length > 0) {
81
+ const entries = searchResults.map(r => ({
82
+ title: r.entry.frontmatter.title,
83
+ category: r.entry.category,
84
+ path: r.entry.path
85
+ }));
86
+
87
+ const categories = relevantCategories.length > 0
88
+ ? relevantCategories
89
+ : [...new Set(searchResults.map(r => r.entry.category))];
90
+
91
+ // Output for Claude Code hook integration (user-facing console logs)
92
+ if (searchResults.length > 0) {
93
+ console.log(`\u{1F4DA} Solvdex: Found ${searchResults.length} relevant entries`);
94
+ for (const r of searchResults.slice(0, 3)) {
95
+ console.log(` - ${r.entry.frontmatter.title} (${r.entry.category})`);
96
+ }
97
+ }
98
+
99
+ // Structured output for Claude Code (includes both old and new format for backward compatibility)
100
+ const output: SessionStartOutput = {
101
+ // Old format (for backward compatibility)
102
+ type: 'wiki_context',
103
+ message: searchResults.length > 0
104
+ ? `Wiki: Found ${searchResults.length} relevant entries`
105
+ : `Wiki: Check ${categories.join(', ')} for related knowledge`,
106
+ categories,
107
+ entries: entries.length > 0 ? entries : undefined,
108
+ // New format (Claude Code integration)
109
+ continue: true,
110
+ hookSpecificOutput: {
111
+ type: 'wiki_context',
112
+ message: searchResults.length > 0
113
+ ? `Found ${searchResults.length} wiki entries`
114
+ : `Relevant categories: ${categories.join(', ')}`,
115
+ categories,
116
+ entries: entries.length > 0 ? entries.slice(0, 3) : undefined
117
+ },
118
+ additionalContext: searchResults.length > 0
119
+ ? formatEntriesForContext(searchResults.slice(0, 3))
120
+ : undefined
121
+ };
122
+
123
+ // Output JSON marker + JSON (MUST be last output)
124
+ console.log('\n__HOOK_OUTPUT__');
125
+ console.log(JSON.stringify(output));
126
+
127
+ return output;
128
+ }
129
+
130
+ return null;
131
+ } catch (error) {
132
+ // Handle validation errors separately
133
+ if (error instanceof ValidationError) {
134
+ console.error(`[Solvdex] Invalid input: ${error.message}`);
135
+ return null;
136
+ }
137
+ // Graceful degradation - log error but don't crash
138
+ console.error(`[Solvdex] Error in session-start hook: ${error instanceof Error ? error.message : 'Unknown error'}`);
139
+ return null;
140
+ }
141
+ }
142
+
143
+ function isRelevantCategory(task: string, category: string): boolean {
144
+ const categoryKeywords = CATEGORY_KEYWORDS[category] || [];
145
+ const taskLower = task.toLowerCase();
146
+ return categoryKeywords.some(kw => taskLower.includes(kw));
147
+ }
148
+
149
+ /**
150
+ * Formats search results into a readable context string for Claude Code.
151
+ */
152
+ function formatEntriesForContext(results: SearchResult[]): string {
153
+ return results.map(r => {
154
+ const e = r.entry;
155
+ return `## ${e.frontmatter.title} (${e.category})\nConfidence: ${e.frontmatter.confidence}\n\n${e.content.substring(0, 300)}...`;
156
+ }).join('\n\n');
157
+ }
158
+
159
+ export default onSessionStart;
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "solvdex",
3
+ "version": "1.0.0",
4
+ "description": "Knowledge management system for Claude Code - auto-captures and retrieves project solutions",
5
+ "main": "dist/src/index.js",
6
+ "types": "dist/src/index.d.ts",
7
+ "files": [
8
+ "dist/",
9
+ "skills/",
10
+ "hooks/",
11
+ "scripts/",
12
+ "README.md"
13
+ ],
14
+ "keywords": ["claude-code", "wiki", "knowledge-base", "documentation"],
15
+ "author": "duc.do",
16
+ "license": "MIT",
17
+ "scripts": {
18
+ "build": "tsc",
19
+ "test": "vitest",
20
+ "test:watch": "vitest watch",
21
+ "lint": "eslint src/",
22
+ "prepublishOnly": "npm run build"
23
+ },
24
+ "dependencies": {
25
+ "gray-matter": "^4.0.3",
26
+ "glob": "^10.3.10",
27
+ "yaml": "^2.3.4"
28
+ },
29
+ "devDependencies": {
30
+ "@types/node": "^20.10.0",
31
+ "typescript": "^5.3.0",
32
+ "vitest": "^1.0.0",
33
+ "eslint": "^8.55.0",
34
+ "@typescript-eslint/eslint-plugin": "^6.13.0",
35
+ "@typescript-eslint/parser": "^6.13.0"
36
+ },
37
+ "engines": {
38
+ "node": ">=18.0.0"
39
+ }
40
+ }
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Solvdex PostToolUseFailure hook - looks up solutions for errors
4
+ """
5
+ import json
6
+ import sys
7
+ import subprocess
8
+ import os
9
+ from pathlib import Path
10
+
11
+ def main():
12
+ try:
13
+ # Read input from stdin
14
+ input_data = json.load(sys.stdin)
15
+ except json.JSONDecodeError as e:
16
+ print(f"Error parsing input: {e}", file=sys.stderr)
17
+ sys.exit(1)
18
+
19
+ # Extract context
20
+ project_root = input_data.get("cwd", os.getcwd())
21
+ error_message = input_data.get("errorMessage", "")
22
+ tool_name = input_data.get("toolName", "")
23
+
24
+ # Call Node.js hook implementation
25
+ plugin_root = Path(__file__).parent.parent
26
+ hook_script = plugin_root / "dist" / "hooks" / "error-lookup.js"
27
+
28
+ if not hook_script.exists():
29
+ # Silent fail if not built yet
30
+ sys.exit(0)
31
+
32
+ try:
33
+ # Prepare context for TypeScript hook
34
+ context = {
35
+ "projectRoot": project_root,
36
+ "errorMessage": error_message,
37
+ "toolName": tool_name
38
+ }
39
+
40
+ # Call the compiled TypeScript hook
41
+ result = subprocess.run(
42
+ ["node", str(hook_script)],
43
+ input=json.dumps(context),
44
+ capture_output=True,
45
+ text=True,
46
+ timeout=30
47
+ )
48
+
49
+ # Output result to stdout (will be shown to user)
50
+ if result.stdout:
51
+ print(result.stdout, end='')
52
+
53
+ # Exit with same code
54
+ sys.exit(result.returncode)
55
+
56
+ except subprocess.TimeoutExpired:
57
+ print("Hook timed out", file=sys.stderr)
58
+ sys.exit(1)
59
+ except Exception as e:
60
+ print(f"Error executing hook: {e}", file=sys.stderr)
61
+ sys.exit(1)
62
+
63
+ if __name__ == "__main__":
64
+ main()
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Solvdex Stop hook - offers to capture knowledge after task completion
4
+ """
5
+ import json
6
+ import sys
7
+ import subprocess
8
+ import os
9
+ from pathlib import Path
10
+
11
+ def main():
12
+ try:
13
+ # Read input from stdin
14
+ input_data = json.load(sys.stdin)
15
+ except json.JSONDecodeError as e:
16
+ print(f"Error parsing input: {e}", file=sys.stderr)
17
+ sys.exit(1)
18
+
19
+ # Extract context
20
+ project_root = input_data.get("cwd", os.getcwd())
21
+
22
+ # Call Node.js hook implementation
23
+ plugin_root = Path(__file__).parent.parent
24
+ hook_script = plugin_root / "dist" / "hooks" / "post-task.js"
25
+
26
+ if not hook_script.exists():
27
+ # Silent fail if not built yet
28
+ sys.exit(0)
29
+
30
+ try:
31
+ # Prepare context for TypeScript hook
32
+ context = {
33
+ "projectRoot": project_root
34
+ }
35
+
36
+ # Call the compiled TypeScript hook
37
+ result = subprocess.run(
38
+ ["node", str(hook_script)],
39
+ input=json.dumps(context),
40
+ capture_output=True,
41
+ text=True,
42
+ timeout=30
43
+ )
44
+
45
+ # Output result to stdout (will be shown to user)
46
+ if result.stdout:
47
+ print(result.stdout, end='')
48
+
49
+ # Exit with same code
50
+ sys.exit(result.returncode)
51
+
52
+ except subprocess.TimeoutExpired:
53
+ print("Hook timed out", file=sys.stderr)
54
+ sys.exit(1)
55
+ except Exception as e:
56
+ print(f"Error executing hook: {e}", file=sys.stderr)
57
+ sys.exit(1)
58
+
59
+ if __name__ == "__main__":
60
+ main()
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Solvdex UserPromptSubmit hook - enriches prompts with relevant wiki context
4
+ """
5
+ import json
6
+ import sys
7
+ import subprocess
8
+ import os
9
+ from pathlib import Path
10
+
11
+ def main():
12
+ try:
13
+ # Read input from stdin
14
+ input_data = json.load(sys.stdin)
15
+ except json.JSONDecodeError as e:
16
+ print(f"Error parsing input: {e}", file=sys.stderr)
17
+ sys.exit(1)
18
+
19
+ # Extract context
20
+ project_root = input_data.get("cwd", os.getcwd())
21
+ prompt = input_data.get("prompt", "")
22
+ file_paths = input_data.get("filePaths", [])
23
+
24
+ # Call Node.js hook implementation
25
+ plugin_root = Path(__file__).parent.parent
26
+ hook_script = plugin_root / "dist" / "hooks" / "prompt-enrich.js"
27
+
28
+ if not hook_script.exists():
29
+ # Silent fail if not built yet
30
+ sys.exit(0)
31
+
32
+ try:
33
+ # Prepare context for TypeScript hook
34
+ context = {
35
+ "projectRoot": project_root,
36
+ "prompt": prompt,
37
+ "filePaths": file_paths
38
+ }
39
+
40
+ # Call the compiled TypeScript hook
41
+ result = subprocess.run(
42
+ ["node", str(hook_script)],
43
+ input=json.dumps(context),
44
+ capture_output=True,
45
+ text=True,
46
+ timeout=30
47
+ )
48
+
49
+ # Output result to stdout (will be shown to user)
50
+ if result.stdout:
51
+ print(result.stdout, end='')
52
+
53
+ # Exit with same code
54
+ sys.exit(result.returncode)
55
+
56
+ except subprocess.TimeoutExpired:
57
+ print("Hook timed out", file=sys.stderr)
58
+ sys.exit(1)
59
+ except Exception as e:
60
+ print(f"Error executing hook: {e}", file=sys.stderr)
61
+ sys.exit(1)
62
+
63
+ if __name__ == "__main__":
64
+ main()
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Solvdex SessionStart hook - surfaces relevant wiki entries at session start
4
+ """
5
+ import json
6
+ import sys
7
+ import subprocess
8
+ import os
9
+ from pathlib import Path
10
+
11
+ def main():
12
+ try:
13
+ # Read input from stdin
14
+ input_data = json.load(sys.stdin)
15
+ except json.JSONDecodeError as e:
16
+ print(f"Error parsing input: {e}", file=sys.stderr)
17
+ sys.exit(1)
18
+
19
+ # Extract context
20
+ project_root = input_data.get("cwd", os.getcwd())
21
+ task_description = input_data.get("taskDescription", "")
22
+ file_paths = input_data.get("filePaths", [])
23
+
24
+ # Call Node.js hook implementation
25
+ plugin_root = Path(__file__).parent.parent
26
+ hook_script = plugin_root / "dist" / "hooks" / "session-start.js"
27
+
28
+ if not hook_script.exists():
29
+ # Silent fail if not built yet
30
+ sys.exit(0)
31
+
32
+ try:
33
+ # Prepare context for TypeScript hook
34
+ context = {
35
+ "projectRoot": project_root,
36
+ "taskDescription": task_description,
37
+ "filePaths": file_paths
38
+ }
39
+
40
+ # Call the compiled TypeScript hook
41
+ result = subprocess.run(
42
+ ["node", str(hook_script)],
43
+ input=json.dumps(context),
44
+ capture_output=True,
45
+ text=True,
46
+ timeout=30
47
+ )
48
+
49
+ # Output result to stdout (will be shown to user)
50
+ if result.stdout:
51
+ print(result.stdout, end='')
52
+
53
+ # Exit with same code
54
+ sys.exit(result.returncode)
55
+
56
+ except subprocess.TimeoutExpired:
57
+ print("Hook timed out", file=sys.stderr)
58
+ sys.exit(1)
59
+ except Exception as e:
60
+ print(f"Error executing hook: {e}", file=sys.stderr)
61
+ sys.exit(1)
62
+
63
+ if __name__ == "__main__":
64
+ main()
@@ -0,0 +1,61 @@
1
+ ---
2
+ name: wiki
3
+ description: Project knowledge wiki - stores and retrieves solutions, patterns, and gotchas across 7 development domains. Use when managing project knowledge, searching for solutions, or capturing learnings.
4
+ user-invocable: true
5
+ disable-model-invocation: false
6
+ ---
7
+
8
+ # Solvdex
9
+
10
+ Project knowledge management with 7 specialized categories for capturing solutions, patterns, and learnings.
11
+
12
+ ## Commands
13
+
14
+ | Command | Description |
15
+ |---------|-------------|
16
+ | `/wiki init` | Create `.wiki/` structure |
17
+ | `/wiki add` | Save current solution |
18
+ | `/wiki search <query>` | Full-text search |
19
+ | `/wiki browse` | List entries |
20
+ | `/wiki status` | Show basic stats |
21
+ | `/wiki stats` | Detailed analytics with usage tracking |
22
+ | `/wiki validate` | Check for issues |
23
+ | `/wiki scan` | Generate stubs from project |
24
+ | `/wiki flag <entry>` | Mark needs review |
25
+ | `/wiki fix <entry>` | Update flagged entry |
26
+ | `/wiki export [file]` | Export wiki to JSON |
27
+ | `/wiki import <file>` | Import from export file |
28
+ | `/wiki test-trigger <pattern> <text>` | Test trigger patterns |
29
+
30
+ ## Agents
31
+
32
+ | Command | Description |
33
+ |---------|-------------|
34
+ | `/wiki explore <query>` | Deep search agent - finds relevant knowledge across all categories |
35
+ | `/wiki capture` | Capture agent - extracts knowledge from conversation and creates entries |
36
+
37
+ ## Quick Start
38
+
39
+ 1. Initialize: `/wiki init`
40
+ 2. Scan project: `/wiki scan`
41
+ 3. Search: `/wiki search timeout error`
42
+
43
+ ## Categories
44
+
45
+ | Category | Purpose |
46
+ |----------|---------|
47
+ | `issues/` | Bug fixes, error solutions |
48
+ | `patterns/` | Reusable code patterns |
49
+ | `gotchas/` | Pitfalls, traps |
50
+ | `testing/` | Test strategies, mocks |
51
+ | `docs/` | Documentation templates |
52
+ | `security/` | Auth, vulnerabilities |
53
+ | `performance/` | Optimizations, profiling |
54
+
55
+ ## Confidence (0-100)
56
+
57
+ - **80+** - Verified, used multiple times
58
+ - **50-79** - Worked once or partially verified
59
+ - **20-49** - Stub or unverified
60
+
61
+ Run `/wiki status` to see wiki health.
@@ -0,0 +1,90 @@
1
+ ---
2
+ name: wiki-add
3
+ description: Add current solution or knowledge to the Solvdex wiki. Analyzes conversation context and creates a structured entry.
4
+ argument-hint: [--category=<cat>]
5
+ user-invocable: true
6
+ disable-model-invocation: true
7
+ ---
8
+
9
+ # Add Solvdex Entry
10
+
11
+ Capture current solution or knowledge as a wiki entry.
12
+
13
+ ## Process
14
+
15
+ 1. Analyze recent conversation context
16
+ 2. Determine category (or use provided)
17
+ 3. Extract:
18
+ - Problem/situation
19
+ - Solution/decision
20
+ - Related files
21
+ - Tags
22
+ 4. Generate entry using category template
23
+ 5. Save to `.wiki/<category>/`
24
+ 6. Show confirmation
25
+
26
+ ## Categories
27
+
28
+ | Category | Use For |
29
+ |----------|---------|
30
+ | issues | Bug fixes, error solutions |
31
+ | patterns | Reusable code patterns |
32
+ | gotchas | Pitfalls, traps |
33
+ | testing | Test strategies, mocks |
34
+ | docs | Documentation templates |
35
+ | security | Auth, vulnerabilities |
36
+ | performance | Optimizations, profiling |
37
+
38
+ ## Implementation
39
+
40
+ ```typescript
41
+ import { createEntry, wikiExists, getTemplate, CONFIDENCE } from 'solvdex';
42
+
43
+ const projectRoot = process.cwd();
44
+
45
+ if (!wikiExists(projectRoot)) {
46
+ console.log('No wiki found. Run `/wiki init` first.');
47
+ return;
48
+ }
49
+
50
+ // Analyze conversation context to extract:
51
+ // - What problem was solved
52
+ // - What solution was applied
53
+ // - What files were involved
54
+ // - Relevant tags
55
+
56
+ const analysis = analyzeConversationContext();
57
+
58
+ const category = args.category || analysis.suggestedCategory;
59
+ const template = getTemplate(category);
60
+
61
+ const entry = createEntry(projectRoot, {
62
+ category,
63
+ title: analysis.title,
64
+ tags: analysis.tags,
65
+ content: {
66
+ [template[0].heading]: analysis.problem,
67
+ [template[1].heading]: analysis.cause || analysis.context,
68
+ [template[2].heading]: analysis.solution,
69
+ },
70
+ trigger: analysis.errorPattern,
71
+ confidence: CONFIDENCE.MEDIUM, // 50 - needs verification
72
+ autoCapture: false
73
+ });
74
+
75
+ console.log(`Wiki: Saved "${entry.frontmatter.title}" to ${category}/`);
76
+ console.log('');
77
+ console.log(`Path: ${entry.path}`);
78
+ console.log(`Tags: ${entry.frontmatter.tags.join(', ')}`);
79
+ console.log(`Confidence: ${entry.frontmatter.confidence}`);
80
+ ```
81
+
82
+ ## Output
83
+
84
+ ```
85
+ Wiki: Saved "Drizzle Enum Migration Fix" to issues/
86
+
87
+ Path: issues/drizzle-enum-migration-fix.md
88
+ Tags: drizzle, database, migration, enum
89
+ Confidence: 50
90
+ ```