bluera-knowledge 0.36.0 → 0.37.1

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 (36) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/CHANGELOG.md +34 -0
  3. package/README.md +1 -1
  4. package/bun.lock +27 -0
  5. package/dist/{chunk-L2SC6J4K.js → chunk-724FNI27.js} +466 -171
  6. package/dist/chunk-724FNI27.js.map +1 -0
  7. package/dist/{chunk-MQQ46BST.js → chunk-F6DGSS2N.js} +2 -2
  8. package/dist/{chunk-DNGE7FZ4.js → chunk-VB5V4RC7.js} +1387 -42
  9. package/dist/chunk-VB5V4RC7.js.map +1 -0
  10. package/dist/index.js +2153 -17
  11. package/dist/index.js.map +1 -1
  12. package/dist/mcp/server.d.ts +37 -3
  13. package/dist/mcp/server.js +2 -2
  14. package/dist/workers/background-worker-cli.js +2 -2
  15. package/hooks/check-ready.sh +17 -7
  16. package/hooks/lib/store_summary.py +111 -0
  17. package/hooks/posttooluse-bk-reminder.py +33 -6
  18. package/hooks/userpromptsubmit-bk-nudge.py +25 -5
  19. package/package.json +3 -1
  20. package/scripts/eval-candidates.sh +235 -0
  21. package/scripts/launch-ui.sh +20 -0
  22. package/scripts/preview-ui.ts +207 -0
  23. package/skills/advanced-workflows/references/combining-workflows.md +17 -0
  24. package/skills/advanced-workflows/references/error-recovery.md +44 -0
  25. package/skills/advanced-workflows/references/handling-large-results.md +48 -0
  26. package/skills/advanced-workflows/references/multi-store-search.md +42 -0
  27. package/skills/search/statusline.md +75 -0
  28. package/skills/store-lifecycle/references/failure-recovery.md +80 -0
  29. package/skills/store-lifecycle/references/indexing-strategies.md +67 -0
  30. package/skills/store-lifecycle/references/job-monitoring.md +72 -0
  31. package/skills/store-lifecycle/references/lifecycle-checklist.md +20 -0
  32. package/skills/store-lifecycle/references/storage-management.md +43 -0
  33. package/skills/ui/SKILL.md +27 -0
  34. package/dist/chunk-DNGE7FZ4.js.map +0 -1
  35. package/dist/chunk-L2SC6J4K.js.map +0 -1
  36. /package/dist/{chunk-MQQ46BST.js.map → chunk-F6DGSS2N.js.map} +0 -0
@@ -0,0 +1,207 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * Preview mcp-ui HTML views in a browser.
4
+ *
5
+ * Usage: bun run preview:ui [stores|search]
6
+ */
7
+
8
+ import { mkdirSync, writeFileSync } from 'node:fs';
9
+ import { join } from 'node:path';
10
+ import { execSync } from 'node:child_process';
11
+ import { renderStoresDashboard } from '../src/mcp/ui/stores-dashboard.js';
12
+ import { renderSearchResults } from '../src/mcp/ui/search-results.js';
13
+
14
+ const view = process.argv[2] ?? 'stores';
15
+ const outDir = join(import.meta.dirname, '..', '.preview');
16
+ mkdirSync(outDir, { recursive: true });
17
+
18
+ if (view === 'stores') {
19
+ const html = renderStoresDashboard([
20
+ {
21
+ id: 'abc-123',
22
+ name: 'mcp-ui',
23
+ type: 'repo',
24
+ url: 'https://github.com/MCP-UI-Org/mcp-ui',
25
+ branch: 'main',
26
+ modelId: 'Xenova/bge-small-en-v1.5',
27
+ createdAt: new Date(Date.now() - 2 * 86400000).toISOString(),
28
+ tags: ['sdk', 'ui', 'mcp'],
29
+ description: 'MCP UI SDK for building interactive web components over MCP',
30
+ },
31
+ {
32
+ id: 'def-456',
33
+ name: 'react',
34
+ type: 'repo',
35
+ url: 'https://github.com/facebook/react',
36
+ branch: 'main',
37
+ modelId: 'Xenova/bge-small-en-v1.5',
38
+ createdAt: new Date(Date.now() - 30 * 86400000).toISOString(),
39
+ tags: ['frontend', 'framework'],
40
+ description: 'The library for web and native user interfaces',
41
+ },
42
+ {
43
+ id: 'ghi-789',
44
+ name: 'project-docs',
45
+ type: 'file',
46
+ path: '/Users/dev/repos/my-project/docs',
47
+ createdAt: new Date(Date.now() - 1 * 86400000).toISOString(),
48
+ description: 'Local project documentation',
49
+ },
50
+ {
51
+ id: 'jkl-012',
52
+ name: 'mdn-web-apis',
53
+ type: 'web',
54
+ url: 'https://developer.mozilla.org/en-US/docs/Web/API',
55
+ createdAt: new Date(Date.now() - 7 * 86400000).toISOString(),
56
+ tags: ['docs', 'web-apis'],
57
+ description: 'MDN Web API reference documentation',
58
+ },
59
+ {
60
+ id: 'mno-345',
61
+ name: 'pending-store',
62
+ type: 'repo',
63
+ url: 'https://github.com/example/lib',
64
+ createdAt: new Date().toISOString(),
65
+ description: 'A store still being indexed',
66
+ },
67
+ ]);
68
+
69
+ const outFile = join(outDir, 'stores.html');
70
+ writeFileSync(outFile, html);
71
+ console.log(`Wrote ${outFile}`);
72
+ execSync(`open "${outFile}"`);
73
+ } else if (view === 'search') {
74
+ const html = renderSearchResults(
75
+ 'createUIResource options and usage',
76
+ [
77
+ {
78
+ id: 'r1',
79
+ score: 0.92,
80
+ summary: {
81
+ type: 'function',
82
+ name: 'createUIResource',
83
+ signature: 'function createUIResource(options: CreateUIResourceOptions): UIResource',
84
+ purpose: 'Creates a UIResource object to include in MCP tool result content arrays',
85
+ location: 'sdks/typescript/server/src/index.ts:32',
86
+ relevanceReason: 'Matches: createUIResource, options, usage',
87
+ storeName: 'mcp-ui',
88
+ },
89
+ context: {
90
+ interfaces: ['CreateUIResourceOptions', 'UIResource'],
91
+ keyImports: ['@modelcontextprotocol/ext-apps'],
92
+ relatedConcepts: ['rawHtml', 'externalUrl', 'encoding', 'mimeType'],
93
+ usage: { calledBy: 12, calls: 3 },
94
+ },
95
+ full: {
96
+ completeCode: `export async function createUIResource(options: CreateUIResourceOptions): Promise<UIResource> {
97
+ let actualContentString: string;
98
+ const mimeType: MimeType = RESOURCE_MIME_TYPE;
99
+
100
+ if (!options.uri.startsWith('ui://')) {
101
+ throw new Error("MCP-UI SDK: URI must start with 'ui://'.");
102
+ }
103
+
104
+ if (options.content.type === 'rawHtml') {
105
+ actualContentString = options.content.htmlString;
106
+ } else if (options.content.type === 'externalUrl') {
107
+ actualContentString = await fetchExternalUrl(options.content.iframeUrl);
108
+ }
109
+ // ...
110
+ }`,
111
+ documentation: 'Creates a UIResource for inclusion in tool results.',
112
+ relatedCode: [
113
+ {
114
+ file: 'types.ts',
115
+ summary: 'Type definitions for CreateUIResourceOptions',
116
+ relationship: 'defines input types',
117
+ },
118
+ ],
119
+ },
120
+ },
121
+ {
122
+ id: 'r2',
123
+ score: 0.78,
124
+ summary: {
125
+ type: 'interface',
126
+ name: 'CreateUIResourceOptions',
127
+ signature: 'interface CreateUIResourceOptions',
128
+ purpose: 'Configuration options for creating a UI resource',
129
+ location: 'sdks/typescript/server/src/types.ts:15',
130
+ relevanceReason: 'Matches: options, createUIResource',
131
+ storeName: 'mcp-ui',
132
+ },
133
+ context: {
134
+ interfaces: ['ResourceContentPayload'],
135
+ keyImports: [],
136
+ relatedConcepts: ['uri', 'content', 'encoding', 'embeddedResourceProps'],
137
+ },
138
+ },
139
+ {
140
+ id: 'r3',
141
+ score: 0.65,
142
+ summary: {
143
+ type: 'documentation',
144
+ name: 'Server Walkthrough',
145
+ purpose: 'Step-by-step guide for integrating mcp-ui into an MCP server',
146
+ location: 'docs/src/guide/server/typescript/walkthrough.md',
147
+ relevanceReason: 'Matches: usage, createUIResource',
148
+ storeName: 'mcp-ui',
149
+ },
150
+ },
151
+ {
152
+ id: 'r4',
153
+ score: 0.41,
154
+ summary: {
155
+ type: 'const',
156
+ name: 'RESOURCE_MIME_TYPE',
157
+ signature: "const RESOURCE_MIME_TYPE = 'text/html;profile=mcp-app'",
158
+ purpose: 'Standard MIME type for MCP UI resources',
159
+ location: 'sdks/typescript/server/src/types.ts:3',
160
+ storeName: 'mcp-ui',
161
+ },
162
+ },
163
+ {
164
+ id: 'r5',
165
+ score: 0.33,
166
+ summary: {
167
+ type: 'example',
168
+ name: 'showRawHtml tool',
169
+ purpose: 'Example tool handler returning a raw HTML UI resource',
170
+ location: 'examples/typescript-server-demo/src/index.ts:79',
171
+ relevanceReason: 'Matches: usage example of createUIResource',
172
+ storeName: 'mcp-ui',
173
+ },
174
+ full: {
175
+ completeCode: `server.registerTool('showRawHtml', {
176
+ title: 'Show Raw HTML',
177
+ description: 'Creates a UI resource displaying raw HTML.',
178
+ inputSchema: {},
179
+ }, async () => {
180
+ const uiResource = await createUIResource({
181
+ uri: 'ui://raw-html-demo',
182
+ content: { type: 'rawHtml', htmlString: '<h1>Hello from Raw HTML</h1>' },
183
+ encoding: 'text',
184
+ });
185
+ return { content: [uiResource] };
186
+ });`,
187
+ },
188
+ },
189
+ ],
190
+ {
191
+ timeMs: 29,
192
+ confidence: 'high',
193
+ mode: 'hybrid',
194
+ stores: {
195
+ 'mcp-ui': { type: 'repo', url: 'https://github.com/MCP-UI-Org/mcp-ui' },
196
+ },
197
+ }
198
+ );
199
+
200
+ const outFile = join(outDir, 'search.html');
201
+ writeFileSync(outFile, html);
202
+ console.log(`Wrote ${outFile}`);
203
+ execSync(`open "${outFile}"`);
204
+ } else {
205
+ console.error(`Unknown view: ${view}. Use "stores" or "search".`);
206
+ process.exit(1);
207
+ }
@@ -0,0 +1,17 @@
1
+ # Combining Workflows
2
+
3
+ Real-world usage often combines these patterns:
4
+
5
+ ```
6
+ User: "I need to understand how Express and Hono handle middleware differently"
7
+
8
+ 1. list_stores() → check if both indexed
9
+ 2. If not: create_store() for missing framework(s)
10
+ 3. check_job_status() → wait for indexing
11
+ 4. search("middleware implementation", stores=['express', 'hono'], detail='minimal')
12
+ 5. Review summaries, identify key files
13
+ 6. get_full_context() for 2-3 most relevant from each framework
14
+ 7. Compare implementations with full context
15
+ ```
16
+
17
+ This multi-step workflow is efficient, targeted, and conserves context.
@@ -0,0 +1,44 @@
1
+ # Error Recovery
2
+
3
+ When operations fail, use these recovery patterns:
4
+
5
+ ### Workflow: Handle Indexing Failures
6
+
7
+ ```
8
+ 1. create_store() fails or job_status shows 'failed'
9
+ → Check error message
10
+ → Common issues:
11
+ - Git auth required (private repo)
12
+ - Invalid URL/path
13
+ - Disk space
14
+ - Network timeout
15
+
16
+ 2. Recovery actions:
17
+ - Auth issue: Provide credentials or use HTTPS
18
+ - Invalid path: Verify URL/path exists
19
+ - Disk space: delete_store() unused stores
20
+ - Network: Retry with smaller repo or use --shallow
21
+
22
+ 3. Verify recovery:
23
+ list_stores() → Check store appeared
24
+ search(test_query, stores=[new_store]) → Verify searchable
25
+ ```
26
+
27
+ **Example:**
28
+
29
+ ```
30
+ create_store('https://github.com/private/repo', 'my-repo')
31
+ → job_id: 'job_xyz'
32
+
33
+ check_job_status('job_xyz')
34
+ → Status: failed
35
+ → Error: "Authentication required for private repository"
36
+
37
+ # Recovery: Use authenticated URL or SSH
38
+ create_store('git@github.com:private/repo.git', 'my-repo')
39
+ → job_id: 'job_xyz2'
40
+
41
+ check_job_status('job_xyz2')
42
+ → Status: completed
43
+ → Success!
44
+ ```
@@ -0,0 +1,48 @@
1
+ # Handling Large Result Sets
2
+
3
+ When initial search returns many results, use progressive detail to avoid context overload:
4
+
5
+ ### Workflow: Progressive Detail Strategy
6
+
7
+ ```
8
+ 1. search(query, detail='minimal', limit=20)
9
+ → Get summaries only (~100 tokens/result)
10
+ → Review all 20 summaries quickly
11
+
12
+ 2. Filter by relevance score:
13
+ - Score > 0.8: Excellent match
14
+ - Score 0.6-0.8: Good match
15
+ - Score < 0.6: Possibly irrelevant
16
+
17
+ 3. For top 3-5 results (score > 0.7):
18
+ get_full_context(selected_ids)
19
+ → Fetch complete code only for relevant items
20
+ → Saves ~80% context vs fetching all upfront
21
+
22
+ 4. If nothing relevant:
23
+ search(refined_query, detail='contextual', limit=10)
24
+ → Try different query with more context
25
+ → Or broaden/narrow the search
26
+ ```
27
+
28
+ **Example:**
29
+
30
+ ```
31
+ # Initial broad search
32
+ search("authentication middleware", detail='minimal', limit=20)
33
+ → 20 results, scores ranging 0.45-0.92
34
+ → Total context: ~2k tokens (minimal)
35
+
36
+ # Filter by score
37
+ Top results (>0.7):
38
+ - Result 3: auth/jwt.ts (score: 0.92)
39
+ - Result 7: middleware/authenticate.ts (score: 0.85)
40
+ - Result 12: auth/session.ts (score: 0.74)
41
+
42
+ # Get full code for top 3 only
43
+ get_full_context(['result_3', 'result_7', 'result_12'])
44
+ → Complete implementations for relevant files only
45
+ → Context: ~3k tokens (vs ~15k if we fetched all 20)
46
+
47
+ # Found what we needed! If not, would refine query and retry.
48
+ ```
@@ -0,0 +1,42 @@
1
+ # Multi-Store Search with Ranking
2
+
3
+ When searching across multiple stores, use ranking to prioritize results:
4
+
5
+ ### Workflow: Cross-Library Search
6
+
7
+ ```
8
+ 1. search(query, limit=10)
9
+ → Searches ALL stores
10
+ → Returns mixed results ranked by relevance
11
+
12
+ 2. Review store distribution:
13
+ - If dominated by one store: might narrow to specific stores
14
+ - If balanced: good cross-library perspective
15
+
16
+ 3. For specific library focus:
17
+ search(query, stores=['lib1', 'lib2'], limit=15)
18
+ → Search only relevant libraries
19
+ → Get more results from target libraries
20
+ ```
21
+
22
+ **Example:**
23
+
24
+ User: "How do different frameworks handle routing?"
25
+
26
+ ```
27
+ # Search all indexed frameworks
28
+ search("routing implementation", intent='find-implementation', limit=15)
29
+ → Result mix:
30
+ - express (score: 0.91)
31
+ - fastapi (score: 0.89)
32
+ - hono (score: 0.87)
33
+ - vue-router (score: 0.82)
34
+ - ...
35
+
36
+ # All stores represented, good comparative view!
37
+
38
+ # If user wants deeper FastAPI focus:
39
+ search("routing implementation", stores=['fastapi', 'starlette'], limit=20)
40
+ → More FastAPI/Starlette-specific results
41
+ → Deeper exploration of Python framework routing
42
+ ```
@@ -0,0 +1,75 @@
1
+ ---
2
+ description: Add bluera-knowledge status indicator to the statusline
3
+ allowed-tools: [Read, Edit, Write, Bash]
4
+ ---
5
+
6
+ # Bluera Knowledge Statusline
7
+
8
+ Add a 📘 blue book icon with MCP connectivity LED to the Claude Code statusline.
9
+
10
+ ## What it shows
11
+
12
+ - `📘●` (green) — MCP server process is running
13
+ - `📘●` (red) — MCP server not detected
14
+
15
+ ## Instructions
16
+
17
+ ### 1. Check if already installed
18
+
19
+ ```bash
20
+ grep -c "# --- bluera-knowledge ---" ~/.claude/statusline.sh 2>/dev/null
21
+ ```
22
+
23
+ **If the count is >= 1: already installed.** Tell the user it's already present and stop. Do NOT inject again.
24
+
25
+ **If 0 or file missing:** proceed to install.
26
+
27
+ ### 2. Read the current statusline
28
+
29
+ ```bash
30
+ cat ~/.claude/statusline.sh
31
+ ```
32
+
33
+ If the file doesn't exist, create a minimal statusline with just the BK module.
34
+
35
+ ### 3. Inject the module
36
+
37
+ Read the module from the plugin:
38
+
39
+ ```bash
40
+ cat "${CLAUDE_PLUGIN_ROOT:-.}/scripts/statusline-module.sh"
41
+ ```
42
+
43
+ Insert the block between `# --- bluera-knowledge ---` and `# --- end bluera-knowledge ---` into `~/.claude/statusline.sh`:
44
+
45
+ - Place the function **before** the final output `printf`/`echo` statement(s)
46
+ - Place it **after** other module functions (like `get_bluera_status`, `get_project_type`, etc.)
47
+ - The leading space in the printf output is intentional — it separates from the previous badge
48
+
49
+ ### 4. Wire into the output
50
+
51
+ Find the output `printf` lines (there are typically 3 — one per context color threshold). Add `%s` and `"$BK_STATUS"` to each, positioned **after** `"$BLUERA_STATUS"` and **before** `"$GIT_INFO"`.
52
+
53
+ For example, if the current format is:
54
+ ```bash
55
+ printf "... %s%s%s ..." "$PROJECT_TYPE" "$BLUERA_STATUS" "$GIT_INFO" ...
56
+ ```
57
+
58
+ Change to:
59
+ ```bash
60
+ printf "... %s%s%s%s ..." "$PROJECT_TYPE" "$BLUERA_STATUS" "$BK_STATUS" "$GIT_INFO" ...
61
+ ```
62
+
63
+ **Important:** Add exactly one `%s` to each format string AND one `"$BK_STATUS"` to each argument list. Count the format specifiers vs arguments to ensure they match.
64
+
65
+ ### 5. Verify
66
+
67
+ ```bash
68
+ bash -n ~/.claude/statusline.sh && echo "Syntax OK"
69
+ ```
70
+
71
+ ### 6. Edge cases
72
+
73
+ - **No statusline.sh exists**: Create a minimal one that reads stdin, runs `get_bk_status`, and echoes the result
74
+ - **Non-bluera preset**: Find the output `echo`/`printf` and append `$BK_STATUS` to it
75
+ - **No `$BLUERA_STATUS` in output**: Place `$BK_STATUS` at the end of the output, before any separators
@@ -0,0 +1,80 @@
1
+ # Handling Indexing Failures
2
+
3
+ ### Common Failure Scenarios
4
+
5
+ **1. Authentication Required (Private Repos)**
6
+ ```
7
+ Error: "Authentication required"
8
+
9
+ Fix options:
10
+ - Use SSH URL: git@github.com:org/repo.git
11
+ - Use HTTPS with token: https://token@github.com/org/repo.git
12
+ - Make repo public (if appropriate)
13
+ ```
14
+
15
+ **2. Invalid URL/Path**
16
+ ```
17
+ Error: "Repository not found" or "Path does not exist"
18
+
19
+ Fix:
20
+ - Verify URL is correct (typos common!)
21
+ - Check path exists and is accessible
22
+ - Ensure network connectivity
23
+ ```
24
+
25
+ **3. Disk Space**
26
+ ```
27
+ Error: "No space left on device"
28
+
29
+ Fix:
30
+ - Check available space: df -h
31
+ - Delete unused stores: delete_store(old_store)
32
+ - Clear .bluera/bluera-knowledge/repos/ manually if needed
33
+ ```
34
+
35
+ **4. Network Timeout**
36
+ ```
37
+ Error: "Connection timeout" or "Failed to fetch"
38
+
39
+ Fix:
40
+ - Retry after checking network
41
+ - Use --shallow for large repos
42
+ - Clone manually then add-folder
43
+ ```
44
+
45
+ **5. Unsupported File Types**
46
+ ```
47
+ Warning: "Skipped 45 binary files"
48
+
49
+ This is normal!
50
+ - Binary files (images, compiled code) are skipped
51
+ - Only text files are indexed
52
+ - Check indexed count vs total to see ratio
53
+ ```
54
+
55
+ ### Recovery Workflow
56
+
57
+ ```
58
+ 1. Attempt fails:
59
+ create_store(url, name) → job fails
60
+
61
+ 2. Check error:
62
+ job_status = check_job_status(job_id)
63
+ error_msg = job_status['error']
64
+
65
+ 3. Determine fix based on error type (see above)
66
+
67
+ 4. Retry with fix:
68
+ create_store(corrected_url, name)
69
+
70
+ 5. Verify success:
71
+ check_job_status(new_job_id)
72
+ → Status: completed
73
+
74
+ list_stores()
75
+ → Store appears in list
76
+
77
+ 6. Test search:
78
+ search(test_query, stores=[name], limit=3)
79
+ → Returns results: Ready to use!
80
+ ```
@@ -0,0 +1,67 @@
1
+ # Indexing Strategies
2
+
3
+ ### Initial Indexing
4
+
5
+ When creating a store, indexing happens automatically in the background:
6
+
7
+ ```
8
+ create_store(url, name)
9
+ → Returns: job_id
10
+ → Background: clone/download → analyze → index
11
+ → Status: pending → running → completed
12
+
13
+ # Monitor progress
14
+ check_job_status(job_id)
15
+ → Progress: 45% (processing src/core.ts)
16
+ → Estimated: ~2 minutes remaining
17
+ ```
18
+
19
+ **Indexing time estimates:**
20
+ - Small library (<1k files): 30-60 seconds
21
+ - Medium library (1k-5k files): 1-3 minutes
22
+ - Large library (>5k files): 3-10 minutes
23
+ - Documentation crawl (100 pages): 1-2 minutes
24
+
25
+ ### Re-indexing (Updates)
26
+
27
+ When library code changes or you modify indexed content:
28
+
29
+ ```
30
+ # For git repos: pull latest changes
31
+ cd .bluera/bluera-knowledge/repos/vue
32
+ git pull origin main
33
+ cd -
34
+
35
+ # Re-index
36
+ /bluera-knowledge:index vue
37
+
38
+ # Or via MCP:
39
+ index_store(store='vue')
40
+ → Re-processes all files
41
+ → Updates vector embeddings
42
+ → Rebuilds search index
43
+ ```
44
+
45
+ **When to re-index:**
46
+ - Library released new version
47
+ - You modified local folder content
48
+ - Search results seem outdated
49
+ - After significant codebase changes
50
+
51
+ **Re-indexing is incremental** - only changed files are re-processed.
52
+
53
+ ### Selective Indexing
54
+
55
+ For large repos, you might want to index specific directories:
56
+
57
+ ```
58
+ # Clone full repo manually
59
+ git clone https://github.com/microsoft/vscode
60
+ cd vscode
61
+
62
+ # Index only specific dirs
63
+ /bluera-knowledge:add-folder ./src/vs/editor --name=vscode-editor
64
+ /bluera-knowledge:add-folder ./src/vs/workbench --name=vscode-workbench
65
+
66
+ # Result: Multiple focused stores instead of one massive store
67
+ ```
@@ -0,0 +1,72 @@
1
+ # Background Job Monitoring
2
+
3
+ All expensive operations run as background jobs: cloning, indexing, crawling.
4
+
5
+ ### Job Lifecycle
6
+
7
+ ```
8
+ 1. create_store() or index_store() → Returns job_id
9
+
10
+ 2. Job states:
11
+ - pending: In queue, not started
12
+ - running: Actively processing
13
+ - completed: Finished successfully
14
+ - failed: Error occurred
15
+
16
+ 3. Monitor progress:
17
+ check_job_status(job_id)
18
+ → Current state, percentage, current file
19
+
20
+ 4. List all jobs:
21
+ list_jobs()
22
+ → See pending, running, completed jobs
23
+
24
+ 5. Cancel if needed:
25
+ cancel_job(job_id)
26
+ → Stops running job, cleans up
27
+ ```
28
+
29
+ ### Best Practices for Job Monitoring
30
+
31
+ **Do poll, but not too frequently:**
32
+ ```
33
+ # Too frequent - wastes resources
34
+ while status != 'completed':
35
+ check_job_status(job_id) # Every second!
36
+ sleep(1)
37
+
38
+ # Reasonable polling interval
39
+ while status != 'completed':
40
+ check_job_status(job_id)
41
+ sleep(15) # Every 15 seconds is fine
42
+ ```
43
+
44
+ **Do handle failures gracefully:**
45
+ ```
46
+ status = check_job_status(job_id)
47
+
48
+ if status['state'] == 'failed':
49
+ error = status['error']
50
+
51
+ if 'auth' in error.lower():
52
+ print("Authentication required - try SSH URL or provide credentials")
53
+ elif 'not found' in error.lower():
54
+ print("Repository/URL not found - check the source")
55
+ elif 'disk' in error.lower():
56
+ print("Disk space issue - delete unused stores")
57
+ else:
58
+ print(f"Unexpected error: {error}")
59
+ ```
60
+
61
+ **Do list jobs to avoid duplicates:**
62
+ ```
63
+ # Before creating new store
64
+ jobs = list_jobs()
65
+ existing = [j for j in jobs if j['store'] == 'vue' and j['state'] in ['pending', 'running']]
66
+
67
+ if existing:
68
+ print(f"Job already running for 'vue': {existing[0]['id']}")
69
+ # Wait for it instead of creating duplicate
70
+ else:
71
+ create_store(...)
72
+ ```
@@ -0,0 +1,20 @@
1
+ # Store Lifecycle Checklist
2
+
3
+ **Creating a Store:**
4
+ - [ ] Choose appropriate source type (repo/folder/crawl)
5
+ - [ ] Use descriptive, consistent naming
6
+ - [ ] Start indexing job
7
+ - [ ] Monitor job status until complete
8
+ - [ ] Verify with list_stores()
9
+ - [ ] Test with sample search
10
+
11
+ **Maintaining a Store:**
12
+ - [ ] Re-index after significant changes
13
+ - [ ] Pull git updates periodically for repo stores
14
+ - [ ] Monitor storage usage
15
+ - [ ] Check search relevance quality
16
+
17
+ **Deleting a Store:**
18
+ - [ ] Confirm no longer needed
19
+ - [ ] Note storage freed
20
+ - [ ] Remove from any documentation referencing it