@milo4jo/contextkit 0.1.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 (110) hide show
  1. package/README.md +181 -0
  2. package/dist/commands/index-cmd.d.ts +3 -0
  3. package/dist/commands/index-cmd.d.ts.map +1 -0
  4. package/dist/commands/index-cmd.js +111 -0
  5. package/dist/commands/index-cmd.js.map +1 -0
  6. package/dist/commands/init.d.ts +3 -0
  7. package/dist/commands/init.d.ts.map +1 -0
  8. package/dist/commands/init.js +56 -0
  9. package/dist/commands/init.js.map +1 -0
  10. package/dist/commands/select.d.ts +3 -0
  11. package/dist/commands/select.d.ts.map +1 -0
  12. package/dist/commands/select.js +64 -0
  13. package/dist/commands/select.js.map +1 -0
  14. package/dist/commands/source/add.d.ts +3 -0
  15. package/dist/commands/source/add.d.ts.map +1 -0
  16. package/dist/commands/source/add.js +87 -0
  17. package/dist/commands/source/add.js.map +1 -0
  18. package/dist/commands/source/index.d.ts +3 -0
  19. package/dist/commands/source/index.d.ts.map +1 -0
  20. package/dist/commands/source/index.js +14 -0
  21. package/dist/commands/source/index.js.map +1 -0
  22. package/dist/commands/source/list.d.ts +3 -0
  23. package/dist/commands/source/list.d.ts.map +1 -0
  24. package/dist/commands/source/list.js +46 -0
  25. package/dist/commands/source/list.js.map +1 -0
  26. package/dist/commands/source/remove.d.ts +3 -0
  27. package/dist/commands/source/remove.d.ts.map +1 -0
  28. package/dist/commands/source/remove.js +38 -0
  29. package/dist/commands/source/remove.js.map +1 -0
  30. package/dist/commands/source.d.ts +3 -0
  31. package/dist/commands/source.d.ts.map +1 -0
  32. package/dist/commands/source.js +153 -0
  33. package/dist/commands/source.js.map +1 -0
  34. package/dist/config/index.d.ts +38 -0
  35. package/dist/config/index.d.ts.map +1 -0
  36. package/dist/config/index.js +100 -0
  37. package/dist/config/index.js.map +1 -0
  38. package/dist/config/types.d.ts +21 -0
  39. package/dist/config/types.d.ts.map +1 -0
  40. package/dist/config/types.js +5 -0
  41. package/dist/config/types.js.map +1 -0
  42. package/dist/db/index.d.ts +14 -0
  43. package/dist/db/index.d.ts.map +1 -0
  44. package/dist/db/index.js +63 -0
  45. package/dist/db/index.js.map +1 -0
  46. package/dist/errors/index.d.ts +30 -0
  47. package/dist/errors/index.d.ts.map +1 -0
  48. package/dist/errors/index.js +51 -0
  49. package/dist/errors/index.js.map +1 -0
  50. package/dist/index.d.ts +3 -0
  51. package/dist/index.d.ts.map +1 -0
  52. package/dist/index.js +90 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/indexer/chunker.d.ts +44 -0
  55. package/dist/indexer/chunker.d.ts.map +1 -0
  56. package/dist/indexer/chunker.js +102 -0
  57. package/dist/indexer/chunker.js.map +1 -0
  58. package/dist/indexer/discovery.d.ts +34 -0
  59. package/dist/indexer/discovery.d.ts.map +1 -0
  60. package/dist/indexer/discovery.js +66 -0
  61. package/dist/indexer/discovery.js.map +1 -0
  62. package/dist/indexer/embeddings.d.ts +32 -0
  63. package/dist/indexer/embeddings.d.ts.map +1 -0
  64. package/dist/indexer/embeddings.js +85 -0
  65. package/dist/indexer/embeddings.js.map +1 -0
  66. package/dist/indexer/index.d.ts +37 -0
  67. package/dist/indexer/index.d.ts.map +1 -0
  68. package/dist/indexer/index.js +123 -0
  69. package/dist/indexer/index.js.map +1 -0
  70. package/dist/selector/budget.d.ts +26 -0
  71. package/dist/selector/budget.d.ts.map +1 -0
  72. package/dist/selector/budget.js +75 -0
  73. package/dist/selector/budget.js.map +1 -0
  74. package/dist/selector/formatter.d.ts +44 -0
  75. package/dist/selector/formatter.d.ts.map +1 -0
  76. package/dist/selector/formatter.js +114 -0
  77. package/dist/selector/formatter.js.map +1 -0
  78. package/dist/selector/index.d.ts +37 -0
  79. package/dist/selector/index.d.ts.map +1 -0
  80. package/dist/selector/index.js +67 -0
  81. package/dist/selector/index.js.map +1 -0
  82. package/dist/selector/scoring.d.ts +26 -0
  83. package/dist/selector/scoring.d.ts.map +1 -0
  84. package/dist/selector/scoring.js +113 -0
  85. package/dist/selector/scoring.js.map +1 -0
  86. package/dist/selector/search.d.ts +29 -0
  87. package/dist/selector/search.d.ts.map +1 -0
  88. package/dist/selector/search.js +48 -0
  89. package/dist/selector/search.js.map +1 -0
  90. package/dist/utils/cli.d.ts +20 -0
  91. package/dist/utils/cli.d.ts.map +1 -0
  92. package/dist/utils/cli.js +19 -0
  93. package/dist/utils/cli.js.map +1 -0
  94. package/dist/utils/format.d.ts +30 -0
  95. package/dist/utils/format.d.ts.map +1 -0
  96. package/dist/utils/format.js +44 -0
  97. package/dist/utils/format.js.map +1 -0
  98. package/dist/utils/output.d.ts +42 -0
  99. package/dist/utils/output.d.ts.map +1 -0
  100. package/dist/utils/output.js +62 -0
  101. package/dist/utils/output.js.map +1 -0
  102. package/dist/utils/prompts.d.ts +23 -0
  103. package/dist/utils/prompts.d.ts.map +1 -0
  104. package/dist/utils/prompts.js +46 -0
  105. package/dist/utils/prompts.js.map +1 -0
  106. package/dist/utils/streams.d.ts +40 -0
  107. package/dist/utils/streams.d.ts.map +1 -0
  108. package/dist/utils/streams.js +61 -0
  109. package/dist/utils/streams.js.map +1 -0
  110. package/package.json +67 -0
package/README.md ADDED
@@ -0,0 +1,181 @@
1
+ # ContextKit 🎯
2
+
3
+ > Smart context selection for AI coding assistants
4
+
5
+ ContextKit indexes your codebase and selects the most relevant chunks for any query — fitting them into your token budget.
6
+
7
+ ## Why?
8
+
9
+ AI coding assistants work better with relevant context. But dumping your entire codebase into the prompt wastes tokens and dilutes focus.
10
+
11
+ ContextKit solves this:
12
+ 1. **Index** your code locally (embeddings stay on your machine)
13
+ 2. **Query** with natural language
14
+ 3. **Get** the most relevant chunks, formatted and ready to paste
15
+
16
+ ## Install
17
+
18
+ ```bash
19
+ npm install -g contextkit
20
+ ```
21
+
22
+ ## Quick Start
23
+
24
+ ```bash
25
+ # Initialize in your project
26
+ cd your-project
27
+ contextkit init
28
+
29
+ # Add source directories
30
+ contextkit source add ./src
31
+ contextkit source add ./lib
32
+
33
+ # Index everything
34
+ contextkit index
35
+
36
+ # Find relevant context
37
+ contextkit select "How does authentication work?"
38
+ ```
39
+
40
+ ## Commands
41
+
42
+ ### `contextkit init`
43
+
44
+ Initialize ContextKit in your project. Creates `.contextkit/` directory with config and database.
45
+
46
+ ```bash
47
+ contextkit init
48
+ ```
49
+
50
+ ### `contextkit source`
51
+
52
+ Manage source directories to index.
53
+
54
+ ```bash
55
+ # Add a source
56
+ contextkit source add ./src
57
+
58
+ # List sources
59
+ contextkit source list
60
+
61
+ # Remove a source
62
+ contextkit source remove src
63
+ ```
64
+
65
+ ### `contextkit index`
66
+
67
+ Index all configured sources. Re-run after code changes.
68
+
69
+ ```bash
70
+ # Index everything
71
+ contextkit index
72
+
73
+ # Index specific source
74
+ contextkit index --source src
75
+ ```
76
+
77
+ ### `contextkit select`
78
+
79
+ Find relevant context for a query.
80
+
81
+ ```bash
82
+ # Basic usage
83
+ contextkit select "How does the auth middleware work?"
84
+
85
+ # Limit token budget (default: 8000)
86
+ contextkit select "error handling" --budget 4000
87
+
88
+ # Filter to specific sources
89
+ contextkit select "database queries" --sources src,lib
90
+
91
+ # Show scoring details
92
+ contextkit select "user validation" --explain
93
+
94
+ # JSON output for scripts
95
+ contextkit select "API routes" --json
96
+ ```
97
+
98
+ ## Output Format
99
+
100
+ ```markdown
101
+ ## src/auth/middleware.ts (lines 1-45)
102
+ ```typescript
103
+ export const authMiddleware = async (req, res, next) => {
104
+ // ... relevant code
105
+ }
106
+ ```
107
+
108
+ ## src/auth/utils.ts (lines 12-30)
109
+ ```typescript
110
+ export function validateToken(token: string) {
111
+ // ... relevant code
112
+ }
113
+ ```
114
+
115
+ ---
116
+ 📊 3,847 tokens | 8 chunks | 2 files
117
+ ```
118
+
119
+ ## How It Works
120
+
121
+ 1. **Chunking**: Files are split into ~500 token chunks with overlap
122
+ 2. **Embedding**: Each chunk is embedded using [gte-small](https://huggingface.co/thenlper/gte-small) (runs locally)
123
+ 3. **Search**: Your query is embedded and compared via cosine similarity
124
+ 4. **Scoring**: Chunks are ranked by similarity + path relevance
125
+ 5. **Budget**: Top chunks are selected until token budget is filled
126
+
127
+ ## Configuration
128
+
129
+ Edit `.contextkit/config.yaml`:
130
+
131
+ ```yaml
132
+ version: 1
133
+
134
+ sources:
135
+ - id: src
136
+ path: ./src
137
+ patterns:
138
+ include:
139
+ - "**/*.ts"
140
+ - "**/*.js"
141
+ exclude:
142
+ - "**/node_modules/**"
143
+ - "**/*.test.ts"
144
+
145
+ settings:
146
+ chunk_size: 500 # Target tokens per chunk
147
+ chunk_overlap: 50 # Overlap between chunks
148
+ ```
149
+
150
+ ## Global Options
151
+
152
+ All commands support:
153
+
154
+ | Option | Description |
155
+ |--------|-------------|
156
+ | `--json` | Output as JSON |
157
+ | `--plain` | No colors (or set `NO_COLOR=1`) |
158
+ | `--quiet` | Suppress non-essential output |
159
+
160
+ ## Privacy
161
+
162
+ - All processing happens locally
163
+ - Embeddings are stored in `.contextkit/index.db`
164
+ - No data leaves your machine
165
+ - Add `.contextkit` to `.gitignore` (done automatically)
166
+
167
+ ## Requirements
168
+
169
+ - Node.js 18+
170
+ - ~500MB disk space for embedding model (downloaded on first run)
171
+
172
+ ## Coming Soon
173
+
174
+ - MCP server for Claude Desktop
175
+ - Agent skill for OpenCode/Clawdbot
176
+ - Configurable embedding models
177
+ - Incremental indexing
178
+
179
+ ## License
180
+
181
+ MIT
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const indexCommand: Command;
3
+ //# sourceMappingURL=index-cmd.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-cmd.d.ts","sourceRoot":"","sources":["../../src/commands/index-cmd.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,eAAO,MAAM,YAAY,SAiIrB,CAAC"}
@@ -0,0 +1,111 @@
1
+ import { Command } from 'commander';
2
+ import cliProgress from 'cli-progress';
3
+ import { loadConfig, ensureInitialized } from '../config/index.js';
4
+ import { openDatabase } from '../db/index.js';
5
+ import { indexSources } from '../indexer/index.js';
6
+ import { writeData, writeMessage, writeSuccess, writeWarning, isTTY } from '../utils/streams.js';
7
+ import { formatCommand, formatDim, formatHighlight } from '../utils/format.js';
8
+ import { getGlobalOpts } from '../utils/cli.js';
9
+ import { SourceNotFoundError } from '../errors/index.js';
10
+ export const indexCommand = new Command('index')
11
+ .description('Index all sources')
12
+ .option('-s, --source <name>', 'Index only a specific source')
13
+ .action(async (options) => {
14
+ ensureInitialized();
15
+ const config = loadConfig();
16
+ const opts = getGlobalOpts(indexCommand);
17
+ if (config.sources.length === 0) {
18
+ writeWarning('No sources configured');
19
+ writeMessage(`Add sources first with ${formatCommand('contextkit source add <path>')}`);
20
+ process.exit(1);
21
+ }
22
+ // Filter sources if --source specified
23
+ let sourcesToIndex = config.sources;
24
+ if (options.source) {
25
+ const source = config.sources.find((s) => s.id === options.source);
26
+ if (!source) {
27
+ throw new SourceNotFoundError(options.source);
28
+ }
29
+ sourcesToIndex = [source];
30
+ }
31
+ // Open database
32
+ const db = openDatabase();
33
+ try {
34
+ if (!opts.quiet) {
35
+ writeMessage('');
36
+ writeMessage('Indexing sources...');
37
+ writeMessage('');
38
+ }
39
+ // Setup progress bar (only in TTY mode)
40
+ let progressBar = null;
41
+ let currentSource = '';
42
+ let currentPhase = '';
43
+ if (isTTY() && !opts.quiet) {
44
+ progressBar = new cliProgress.SingleBar({
45
+ format: `{phase} ${formatHighlight('[{source}]')} {bar} {value}/{total}`,
46
+ barCompleteChar: '█',
47
+ barIncompleteChar: '░',
48
+ hideCursor: true,
49
+ }, cliProgress.Presets.shades_classic);
50
+ }
51
+ // Progress callback
52
+ const onProgress = (progress) => {
53
+ const phaseLabel = {
54
+ discovery: 'Reading files ',
55
+ chunking: 'Chunking ',
56
+ embedding: 'Embedding ',
57
+ storing: 'Storing ',
58
+ }[progress.phase];
59
+ if (progressBar) {
60
+ if (currentSource !== progress.sourceId || currentPhase !== progress.phase) {
61
+ if (currentSource) {
62
+ progressBar.stop();
63
+ }
64
+ currentSource = progress.sourceId;
65
+ currentPhase = progress.phase;
66
+ progressBar.start(progress.total || 1, 0, {
67
+ phase: phaseLabel,
68
+ source: progress.sourceId,
69
+ });
70
+ }
71
+ progressBar.update(progress.current);
72
+ }
73
+ else if (!opts.quiet) {
74
+ // Non-TTY: simple line output
75
+ if (progress.current === progress.total) {
76
+ writeMessage(`${phaseLabel} [${progress.sourceId}]: ${progress.current}/${progress.total}`);
77
+ }
78
+ }
79
+ };
80
+ // Run indexing
81
+ const stats = await indexSources(sourcesToIndex, process.cwd(), db, {
82
+ chunkSize: config.settings.chunk_size,
83
+ chunkOverlap: config.settings.chunk_overlap,
84
+ }, onProgress);
85
+ // Stop progress bar
86
+ if (progressBar) {
87
+ progressBar.stop();
88
+ }
89
+ // Output results
90
+ if (!opts.quiet) {
91
+ writeMessage('');
92
+ const timeStr = (stats.timeMs / 1000).toFixed(1);
93
+ writeSuccess(`Indexed ${stats.chunks} chunks from ${stats.files} files in ${timeStr}s`);
94
+ if (stats.skipped > 0) {
95
+ writeMessage(formatDim(` (${stats.skipped} files skipped - too large or binary)`));
96
+ }
97
+ writeMessage('');
98
+ }
99
+ // JSON output
100
+ if (opts.json) {
101
+ writeData(JSON.stringify({
102
+ status: 'success',
103
+ stats,
104
+ }, null, 2));
105
+ }
106
+ }
107
+ finally {
108
+ db.close();
109
+ }
110
+ });
111
+ //# sourceMappingURL=index-cmd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-cmd.js","sourceRoot":"","sources":["../../src/commands/index-cmd.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const initCommand: Command;
3
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,eAAO,MAAM,WAAW,SAoDpB,CAAC"}
@@ -0,0 +1,56 @@
1
+ import { Command } from 'commander';
2
+ import { existsSync, mkdirSync, writeFileSync, appendFileSync, readFileSync, rmSync } from 'fs';
3
+ import { join } from 'path';
4
+ import { getDefaultConfig, CONFIG_FILE, INDEX_DB } from '../config/index.js';
5
+ import { initDatabase } from '../db/index.js';
6
+ import { writeSuccess, writeMessage } from '../utils/streams.js';
7
+ import { formatPath, formatCommand, formatBold } from '../utils/format.js';
8
+ import { AlreadyInitializedError } from '../errors/index.js';
9
+ export const initCommand = new Command('init')
10
+ .description('Initialize ContextKit in current directory')
11
+ .option('-f, --force', 'Reinitialize (deletes existing index)')
12
+ .action(async (options) => {
13
+ const cwd = process.cwd();
14
+ const contextKitDir = join(cwd, '.contextkit');
15
+ const configPath = join(contextKitDir, CONFIG_FILE);
16
+ const dbPath = join(contextKitDir, INDEX_DB);
17
+ const gitignorePath = join(cwd, '.gitignore');
18
+ // Check if already initialized
19
+ if (existsSync(contextKitDir) && !options.force) {
20
+ throw new AlreadyInitializedError();
21
+ }
22
+ // Clean existing if --force
23
+ if (existsSync(contextKitDir) && options.force) {
24
+ rmSync(contextKitDir, { recursive: true });
25
+ }
26
+ // Create directory
27
+ mkdirSync(contextKitDir, { recursive: true });
28
+ // Create config file
29
+ const config = getDefaultConfig();
30
+ writeFileSync(configPath, config);
31
+ writeSuccess(`Created ${formatPath('.contextkit/config.yaml')}`);
32
+ // Initialize database
33
+ initDatabase(dbPath);
34
+ writeSuccess(`Created ${formatPath('.contextkit/index.db')}`);
35
+ // Add to .gitignore
36
+ const gitignoreEntry = '\n# ContextKit\n.contextkit/index.db\n';
37
+ if (existsSync(gitignorePath)) {
38
+ const content = readFileSync(gitignorePath, 'utf-8');
39
+ if (!content.includes('.contextkit')) {
40
+ appendFileSync(gitignorePath, gitignoreEntry);
41
+ writeSuccess(`Added ${formatPath('.contextkit')} to .gitignore`);
42
+ }
43
+ }
44
+ else {
45
+ writeFileSync(gitignorePath, gitignoreEntry.trim() + '\n');
46
+ writeSuccess(`Created .gitignore with ${formatPath('.contextkit')}`);
47
+ }
48
+ // Next steps
49
+ writeMessage('');
50
+ writeMessage(formatBold('Next steps:'));
51
+ writeMessage(` 1. Add sources: ${formatCommand('contextkit source add ./src')}`);
52
+ writeMessage(` 2. Index: ${formatCommand('contextkit index')}`);
53
+ writeMessage(` 3. Select context: ${formatCommand('contextkit select "your query"')}`);
54
+ writeMessage('');
55
+ });
56
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const selectCommand: Command;
3
+ //# sourceMappingURL=select.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../src/commands/select.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,eAAO,MAAM,aAAa,SA4DtB,CAAC"}
@@ -0,0 +1,64 @@
1
+ import { Command } from 'commander';
2
+ import { ensureInitialized } from '../config/index.js';
3
+ import { openDatabase } from '../db/index.js';
4
+ import { selectContext } from '../selector/index.js';
5
+ import { writeData, writeMessage, writeWarning } from '../utils/streams.js';
6
+ import { formatCommand, formatDim } from '../utils/format.js';
7
+ import { getGlobalOpts } from '../utils/cli.js';
8
+ import { InvalidUsageError } from '../errors/index.js';
9
+ export const selectCommand = new Command('select')
10
+ .description('Select context for a query')
11
+ .argument('<query>', 'The query to find context for')
12
+ .option('-b, --budget <tokens>', 'Maximum tokens to include', '8000')
13
+ .option('-f, --format <format>', 'Output format: text, json', 'text')
14
+ .option('-s, --sources <sources>', 'Filter sources (comma-separated)')
15
+ .option('--explain', 'Show scoring details')
16
+ .action(async (query, options) => {
17
+ ensureInitialized();
18
+ const opts = getGlobalOpts(selectCommand);
19
+ const budget = parseInt(options.budget, 10);
20
+ if (isNaN(budget) || budget <= 0) {
21
+ throw new InvalidUsageError('Budget must be a positive number.');
22
+ }
23
+ // Parse sources filter
24
+ const sources = options.sources
25
+ ? options.sources.split(',').map((s) => s.trim())
26
+ : undefined;
27
+ // Open database
28
+ const db = openDatabase();
29
+ try {
30
+ // Run selection
31
+ const result = await selectContext(db, {
32
+ query,
33
+ budget,
34
+ sources,
35
+ explain: options.explain,
36
+ });
37
+ // Handle empty index
38
+ if (result.isEmpty) {
39
+ writeWarning('No indexed content found');
40
+ writeMessage(`Run ${formatCommand('contextkit index')} first.`);
41
+ return;
42
+ }
43
+ // Handle no results
44
+ if (result.output.data.chunks.length === 0) {
45
+ writeMessage('');
46
+ writeMessage(formatDim('No relevant context found for this query.'));
47
+ writeMessage(formatDim('Try a different query or add more sources.'));
48
+ writeMessage('');
49
+ return;
50
+ }
51
+ // Output based on format
52
+ if (options.format === 'json' || opts.json) {
53
+ writeData(JSON.stringify(result.output.data, null, 2));
54
+ }
55
+ else {
56
+ // Text output goes to stdout (it's the data)
57
+ writeData(result.output.text);
58
+ }
59
+ }
60
+ finally {
61
+ db.close();
62
+ }
63
+ });
64
+ //# sourceMappingURL=select.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select.js","sourceRoot":"","sources":["../../src/commands/select.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const addCommand: Command;
3
+ //# sourceMappingURL=add.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../../src/commands/source/add.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgBpC,eAAO,MAAM,UAAU,SA2DnB,CAAC"}
@@ -0,0 +1,87 @@
1
+ import { Command } from 'commander';
2
+ import { existsSync, statSync } from 'fs';
3
+ import { resolve, relative, basename } from 'path';
4
+ import fg from 'fast-glob';
5
+ import { loadConfig, saveConfig, ensureInitialized } from '../../config/index.js';
6
+ import { writeSuccess, writeMessage } from '../../utils/streams.js';
7
+ import { formatCommand, formatHighlight } from '../../utils/format.js';
8
+ import { PathNotFoundError, SourceExistsError, InvalidUsageError } from '../../errors/index.js';
9
+ /** Default file patterns to include */
10
+ const DEFAULT_INCLUDE = ['**/*.ts', '**/*.js', '**/*.tsx', '**/*.jsx', '**/*.md', '**/*.json'];
11
+ /** Default patterns to exclude */
12
+ const DEFAULT_EXCLUDE = ['**/node_modules/**', '**/dist/**', '**/.git/**'];
13
+ export const addCommand = new Command('add')
14
+ .description('Add a directory as a source')
15
+ .argument('<path>', 'Directory path to add')
16
+ .option('-n, --name <name>', 'Custom name for the source')
17
+ .option('-i, --include <patterns...>', 'Include patterns (glob)')
18
+ .option('-e, --exclude <patterns...>', 'Exclude patterns (glob)')
19
+ .action(async (path, options) => {
20
+ ensureInitialized();
21
+ const absolutePath = resolve(process.cwd(), path);
22
+ const relativePath = './' + relative(process.cwd(), absolutePath);
23
+ // Validate path exists
24
+ if (!existsSync(absolutePath)) {
25
+ const suggestion = findSimilarPath(path);
26
+ throw new PathNotFoundError(path, suggestion);
27
+ }
28
+ // Validate it's a directory
29
+ if (!statSync(absolutePath).isDirectory()) {
30
+ throw new InvalidUsageError(`'${path}' is a file, not a directory.`);
31
+ }
32
+ const config = loadConfig();
33
+ const sourceId = options.name || basename(absolutePath);
34
+ // Check for duplicates
35
+ const existing = config.sources.find((s) => s.id === sourceId);
36
+ if (existing) {
37
+ throw new SourceExistsError(sourceId, existing.path);
38
+ }
39
+ // Resolve patterns
40
+ const include = options.include || DEFAULT_INCLUDE;
41
+ const exclude = options.exclude || DEFAULT_EXCLUDE;
42
+ // Count matching files
43
+ const files = fg.sync(include, {
44
+ cwd: absolutePath,
45
+ ignore: exclude,
46
+ onlyFiles: true,
47
+ });
48
+ // Create and save source
49
+ const source = {
50
+ id: sourceId,
51
+ path: relativePath,
52
+ patterns: { include, exclude },
53
+ };
54
+ config.sources.push(source);
55
+ saveConfig(config);
56
+ // Output
57
+ writeSuccess(`Added source '${formatHighlight(sourceId)}'`);
58
+ writeMessage(` Path: ${relativePath}`);
59
+ writeMessage(` Files: ${files.length} (${summarizeExtensions(files)})`);
60
+ writeMessage('');
61
+ writeMessage(`Run ${formatCommand('contextkit index')} to index this source.`);
62
+ });
63
+ /**
64
+ * Find a similar path to suggest
65
+ */
66
+ function findSimilarPath(path) {
67
+ const parent = resolve(path, '..');
68
+ if (!existsSync(parent))
69
+ return undefined;
70
+ const entries = fg.sync(['*'], { cwd: parent, onlyDirectories: true });
71
+ const needle = basename(path).toLowerCase();
72
+ return entries.find((e) => e.toLowerCase().includes(needle));
73
+ }
74
+ /**
75
+ * Summarize file extensions for display
76
+ */
77
+ function summarizeExtensions(files) {
78
+ const exts = new Set();
79
+ for (const file of files) {
80
+ const ext = file.split('.').pop();
81
+ if (ext)
82
+ exts.add(ext);
83
+ }
84
+ const list = Array.from(exts).slice(0, 5).join(', ');
85
+ return exts.size > 5 ? `${list}...` : list;
86
+ }
87
+ //# sourceMappingURL=add.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add.js","sourceRoot":"","sources":["../../../src/commands/source/add.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const sourceCommand: Command;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/source/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,eAAO,MAAM,aAAa,SAQtB,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { Command } from 'commander';
2
+ import { addCommand } from './add.js';
3
+ import { listCommand } from './list.js';
4
+ import { removeCommand } from './remove.js';
5
+ export const sourceCommand = new Command('source')
6
+ .description('Manage sources')
7
+ .addCommand(addCommand)
8
+ .addCommand(listCommand)
9
+ .addCommand(removeCommand)
10
+ .action(() => {
11
+ // Show help when no subcommand given
12
+ sourceCommand.help();
13
+ });
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/source/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;KAC/C,WAAW,CAAC,gBAAgB,CAAC;KAC7B,UAAU,CAAC,UAAU,CAAC;KACtB,UAAU,CAAC,WAAW,CAAC;KACvB,UAAU,CAAC,aAAa,CAAC;KACzB,MAAM,CAAC,GAAG,EAAE;IACX,qCAAqC;IACrC,aAAa,CAAC,IAAI,EAAE,CAAC;AACvB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const listCommand: Command;
3
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/source/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,eAAO,MAAM,WAAW,SA6CtB,CAAC"}
@@ -0,0 +1,46 @@
1
+ import { Command } from 'commander';
2
+ import { loadConfig, ensureInitialized } from '../../config/index.js';
3
+ import { writeData, writeMessage } from '../../utils/streams.js';
4
+ import { formatCommand, formatBold, formatGray } from '../../utils/format.js';
5
+ import { getGlobalOpts } from '../../utils/cli.js';
6
+ export const listCommand = new Command('list').description('List configured sources').action(() => {
7
+ ensureInitialized();
8
+ const config = loadConfig();
9
+ const opts = getGlobalOpts(listCommand);
10
+ if (config.sources.length === 0) {
11
+ if (opts.json) {
12
+ writeData(JSON.stringify({ sources: [] }));
13
+ }
14
+ else if (!opts.quiet) {
15
+ writeMessage('No sources configured.');
16
+ writeMessage(`Add one with ${formatCommand('contextkit source add <path>')}`);
17
+ }
18
+ return;
19
+ }
20
+ // JSON output
21
+ if (opts.json) {
22
+ writeData(JSON.stringify({ sources: config.sources }, null, 2));
23
+ return;
24
+ }
25
+ // Plain output (for piping)
26
+ if (opts.plain) {
27
+ for (const source of config.sources) {
28
+ writeData(`${source.id}\t${source.path}`);
29
+ }
30
+ return;
31
+ }
32
+ // Table output
33
+ if (!opts.quiet) {
34
+ writeMessage('');
35
+ writeMessage(formatBold('Sources:'));
36
+ writeMessage(` ${formatGray('NAME'.padEnd(15))} ${formatGray('PATH')}`);
37
+ }
38
+ for (const source of config.sources) {
39
+ writeMessage(` ${source.id.padEnd(15)} ${source.path}`);
40
+ }
41
+ if (!opts.quiet) {
42
+ writeMessage('');
43
+ writeMessage(`Total: ${config.sources.length} source${config.sources.length === 1 ? '' : 's'}`);
44
+ }
45
+ });
46
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/source/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACtE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,yBAAyB,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE;IAChG,iBAAiB,EAAE,CAAC;IAEpB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,IAAI,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IAExC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAC7C,CAAC;aAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YACvB,YAAY,CAAC,wBAAwB,CAAC,CAAC;YACvC,YAAY,CAAC,gBAAgB,aAAa,CAAC,8BAA8B,CAAC,EAAE,CAAC,CAAC;QAChF,CAAC;QACD,OAAO;IACT,CAAC;IAED,cAAc;IACd,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAChE,OAAO;IACT,CAAC;IAED,4BAA4B;IAC5B,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACpC,SAAS,CAAC,GAAG,MAAM,CAAC,EAAE,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO;IACT,CAAC;IAED,eAAe;IACf,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAChB,YAAY,CAAC,EAAE,CAAC,CAAC;QACjB,YAAY,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC;QACrC,YAAY,CAAC,KAAK,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC;IAED,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACpC,YAAY,CAAC,KAAK,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAChB,YAAY,CAAC,EAAE,CAAC,CAAC;QACjB,YAAY,CAAC,UAAU,MAAM,CAAC,OAAO,CAAC,MAAM,UAAU,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAClG,CAAC;AACH,CAAC,CAAC,CAAC"}