ctx-pilot 0.9.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 (136) hide show
  1. package/LICENSE +21 -0
  2. package/LICENSE-COMMERCIAL +32 -0
  3. package/README.md +314 -0
  4. package/dist/cli.d.ts +3 -0
  5. package/dist/cli.d.ts.map +1 -0
  6. package/dist/cli.js +577 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/config/index.d.ts +9 -0
  9. package/dist/config/index.d.ts.map +1 -0
  10. package/dist/config/index.js +67 -0
  11. package/dist/config/index.js.map +1 -0
  12. package/dist/config/schema.d.ts +22 -0
  13. package/dist/config/schema.d.ts.map +1 -0
  14. package/dist/config/schema.js +9 -0
  15. package/dist/config/schema.js.map +1 -0
  16. package/dist/indexer/file-scanner.d.ts +6 -0
  17. package/dist/indexer/file-scanner.d.ts.map +1 -0
  18. package/dist/indexer/file-scanner.js +37 -0
  19. package/dist/indexer/file-scanner.js.map +1 -0
  20. package/dist/indexer/index.d.ts +10 -0
  21. package/dist/indexer/index.d.ts.map +1 -0
  22. package/dist/indexer/index.js +123 -0
  23. package/dist/indexer/index.js.map +1 -0
  24. package/dist/indexer/parsers/asciidoc.d.ts +3 -0
  25. package/dist/indexer/parsers/asciidoc.d.ts.map +1 -0
  26. package/dist/indexer/parsers/asciidoc.js +55 -0
  27. package/dist/indexer/parsers/asciidoc.js.map +1 -0
  28. package/dist/indexer/parsers/c.d.ts +3 -0
  29. package/dist/indexer/parsers/c.d.ts.map +1 -0
  30. package/dist/indexer/parsers/c.js +93 -0
  31. package/dist/indexer/parsers/c.js.map +1 -0
  32. package/dist/indexer/parsers/csharp.d.ts +3 -0
  33. package/dist/indexer/parsers/csharp.d.ts.map +1 -0
  34. package/dist/indexer/parsers/csharp.js +79 -0
  35. package/dist/indexer/parsers/csharp.js.map +1 -0
  36. package/dist/indexer/parsers/dart.d.ts +3 -0
  37. package/dist/indexer/parsers/dart.d.ts.map +1 -0
  38. package/dist/indexer/parsers/dart.js +81 -0
  39. package/dist/indexer/parsers/dart.js.map +1 -0
  40. package/dist/indexer/parsers/go.d.ts +3 -0
  41. package/dist/indexer/parsers/go.d.ts.map +1 -0
  42. package/dist/indexer/parsers/go.js +64 -0
  43. package/dist/indexer/parsers/go.js.map +1 -0
  44. package/dist/indexer/parsers/index.d.ts +4 -0
  45. package/dist/indexer/parsers/index.d.ts.map +1 -0
  46. package/dist/indexer/parsers/index.js +109 -0
  47. package/dist/indexer/parsers/index.js.map +1 -0
  48. package/dist/indexer/parsers/java.d.ts +3 -0
  49. package/dist/indexer/parsers/java.d.ts.map +1 -0
  50. package/dist/indexer/parsers/java.js +84 -0
  51. package/dist/indexer/parsers/java.js.map +1 -0
  52. package/dist/indexer/parsers/javascript.d.ts +3 -0
  53. package/dist/indexer/parsers/javascript.d.ts.map +1 -0
  54. package/dist/indexer/parsers/javascript.js +78 -0
  55. package/dist/indexer/parsers/javascript.js.map +1 -0
  56. package/dist/indexer/parsers/markdown.d.ts +3 -0
  57. package/dist/indexer/parsers/markdown.d.ts.map +1 -0
  58. package/dist/indexer/parsers/markdown.js +67 -0
  59. package/dist/indexer/parsers/markdown.js.map +1 -0
  60. package/dist/indexer/parsers/php.d.ts +3 -0
  61. package/dist/indexer/parsers/php.d.ts.map +1 -0
  62. package/dist/indexer/parsers/php.js +78 -0
  63. package/dist/indexer/parsers/php.js.map +1 -0
  64. package/dist/indexer/parsers/plain.d.ts +3 -0
  65. package/dist/indexer/parsers/plain.d.ts.map +1 -0
  66. package/dist/indexer/parsers/plain.js +18 -0
  67. package/dist/indexer/parsers/plain.js.map +1 -0
  68. package/dist/indexer/parsers/python.d.ts +3 -0
  69. package/dist/indexer/parsers/python.d.ts.map +1 -0
  70. package/dist/indexer/parsers/python.js +64 -0
  71. package/dist/indexer/parsers/python.js.map +1 -0
  72. package/dist/indexer/parsers/rst.d.ts +3 -0
  73. package/dist/indexer/parsers/rst.d.ts.map +1 -0
  74. package/dist/indexer/parsers/rst.js +67 -0
  75. package/dist/indexer/parsers/rst.js.map +1 -0
  76. package/dist/indexer/parsers/ruby.d.ts +3 -0
  77. package/dist/indexer/parsers/ruby.d.ts.map +1 -0
  78. package/dist/indexer/parsers/ruby.js +77 -0
  79. package/dist/indexer/parsers/ruby.js.map +1 -0
  80. package/dist/indexer/parsers/rust.d.ts +3 -0
  81. package/dist/indexer/parsers/rust.d.ts.map +1 -0
  82. package/dist/indexer/parsers/rust.js +83 -0
  83. package/dist/indexer/parsers/rust.js.map +1 -0
  84. package/dist/indexer/parsers/shader.d.ts +3 -0
  85. package/dist/indexer/parsers/shader.d.ts.map +1 -0
  86. package/dist/indexer/parsers/shader.js +81 -0
  87. package/dist/indexer/parsers/shader.js.map +1 -0
  88. package/dist/indexer/parsers/shell.d.ts +3 -0
  89. package/dist/indexer/parsers/shell.d.ts.map +1 -0
  90. package/dist/indexer/parsers/shell.js +77 -0
  91. package/dist/indexer/parsers/shell.js.map +1 -0
  92. package/dist/indexer/parsers/structured.d.ts +3 -0
  93. package/dist/indexer/parsers/structured.d.ts.map +1 -0
  94. package/dist/indexer/parsers/structured.js +104 -0
  95. package/dist/indexer/parsers/structured.js.map +1 -0
  96. package/dist/indexer/parsers/swift.d.ts +3 -0
  97. package/dist/indexer/parsers/swift.d.ts.map +1 -0
  98. package/dist/indexer/parsers/swift.js +89 -0
  99. package/dist/indexer/parsers/swift.js.map +1 -0
  100. package/dist/indexer/parsers/toml.d.ts +3 -0
  101. package/dist/indexer/parsers/toml.d.ts.map +1 -0
  102. package/dist/indexer/parsers/toml.js +58 -0
  103. package/dist/indexer/parsers/toml.js.map +1 -0
  104. package/dist/indexer/parsers/xml.d.ts +3 -0
  105. package/dist/indexer/parsers/xml.d.ts.map +1 -0
  106. package/dist/indexer/parsers/xml.js +73 -0
  107. package/dist/indexer/parsers/xml.js.map +1 -0
  108. package/dist/search/index.d.ts +5 -0
  109. package/dist/search/index.d.ts.map +1 -0
  110. package/dist/search/index.js +84 -0
  111. package/dist/search/index.js.map +1 -0
  112. package/dist/search/keywords.d.ts +9 -0
  113. package/dist/search/keywords.d.ts.map +1 -0
  114. package/dist/search/keywords.js +79 -0
  115. package/dist/search/keywords.js.map +1 -0
  116. package/dist/types.d.ts +44 -0
  117. package/dist/types.d.ts.map +1 -0
  118. package/dist/types.js +2 -0
  119. package/dist/types.js.map +1 -0
  120. package/dist/utils/gitignore.d.ts +5 -0
  121. package/dist/utils/gitignore.d.ts.map +1 -0
  122. package/dist/utils/gitignore.js +31 -0
  123. package/dist/utils/gitignore.js.map +1 -0
  124. package/dist/utils/index.d.ts +3 -0
  125. package/dist/utils/index.d.ts.map +1 -0
  126. package/dist/utils/index.js +3 -0
  127. package/dist/utils/index.js.map +1 -0
  128. package/dist/utils/paths.d.ts +8 -0
  129. package/dist/utils/paths.d.ts.map +1 -0
  130. package/dist/utils/paths.js +23 -0
  131. package/dist/utils/paths.js.map +1 -0
  132. package/dist/utils/tokens.d.ts +3 -0
  133. package/dist/utils/tokens.d.ts.map +1 -0
  134. package/dist/utils/tokens.js +22 -0
  135. package/dist/utils/tokens.js.map +1 -0
  136. package/package.json +77 -0
@@ -0,0 +1,79 @@
1
+ // Common English stopwords to filter out
2
+ const STOPWORDS = new Set([
3
+ 'a', 'an', 'the', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for',
4
+ 'of', 'with', 'by', 'from', 'as', 'is', 'was', 'are', 'were', 'been',
5
+ 'be', 'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'could',
6
+ 'should', 'may', 'might', 'must', 'shall', 'can', 'need', 'dare', 'ought',
7
+ 'used', 'it', 'its', 'this', 'that', 'these', 'those', 'i', 'you', 'he',
8
+ 'she', 'we', 'they', 'what', 'which', 'who', 'whom', 'whose', 'where',
9
+ 'when', 'why', 'how', 'all', 'each', 'every', 'both', 'few', 'more',
10
+ 'most', 'other', 'some', 'such', 'no', 'nor', 'not', 'only', 'own',
11
+ 'same', 'so', 'than', 'too', 'very', 'just', 'also', 'now', 'here',
12
+ 'there', 'if', 'then', 'else', 'any', 'about', 'into', 'through',
13
+ 'during', 'before', 'after', 'above', 'below', 'between', 'under',
14
+ 'again', 'further', 'once', 'up', 'down', 'out', 'off', 'over',
15
+ ]);
16
+ // Minimum keyword length
17
+ const MIN_KEYWORD_LENGTH = 2;
18
+ // Maximum keywords to extract
19
+ const MAX_KEYWORDS = 50;
20
+ export function extractKeywords(text) {
21
+ if (!text)
22
+ return [];
23
+ // Convert to lowercase and split on non-word characters
24
+ const words = text
25
+ .toLowerCase()
26
+ .split(/[^a-z0-9]+/)
27
+ .filter(word => word.length >= MIN_KEYWORD_LENGTH &&
28
+ !STOPWORDS.has(word) &&
29
+ !/^\d+$/.test(word) // Filter pure numbers
30
+ );
31
+ // Count occurrences
32
+ const counts = new Map();
33
+ for (const word of words) {
34
+ counts.set(word, (counts.get(word) || 0) + 1);
35
+ }
36
+ // Sort by frequency and take top keywords
37
+ const sorted = Array.from(counts.entries())
38
+ .sort((a, b) => b[1] - a[1])
39
+ .slice(0, MAX_KEYWORDS)
40
+ .map(([word]) => word);
41
+ return sorted;
42
+ }
43
+ export function normalizeQuery(query) {
44
+ return extractKeywords(query);
45
+ }
46
+ /**
47
+ * Extract high-value topics from a user prompt.
48
+ * More aggressive than extractKeywords - captures quoted terms,
49
+ * file paths, technical terms, and code references.
50
+ */
51
+ export function extractTopics(prompt) {
52
+ const topics = [];
53
+ // Quoted terms (user explicitly highlighting something)
54
+ const quoted = prompt.match(/"([^"]+)"/g) || [];
55
+ topics.push(...quoted.map(q => q.replace(/"/g, '')));
56
+ // Single-quoted terms
57
+ const singleQuoted = prompt.match(/'([^']+)'/g) || [];
58
+ topics.push(...singleQuoted.map(q => q.replace(/'/g, '')));
59
+ // File paths mentioned
60
+ const paths = prompt.match(/[\w\-./]+\.(md|yaml|yml|ts|tsx|js|jsx|py|go|rs|json|txt)/gi) || [];
61
+ topics.push(...paths);
62
+ // Code references in backticks
63
+ const code = prompt.match(/`([^`]+)`/g) || [];
64
+ topics.push(...code.map(c => c.replace(/`/g, '')));
65
+ // Technical terms: PascalCase or camelCase
66
+ const camelCase = prompt.match(/[a-z]+[A-Z][a-zA-Z]*/g) || [];
67
+ topics.push(...camelCase);
68
+ const pascalCase = prompt.match(/[A-Z][a-z]+(?:[A-Z][a-z]+)+/g) || [];
69
+ topics.push(...pascalCase);
70
+ // ALL_CAPS terms (constants, acronyms)
71
+ const allCaps = prompt.match(/\b[A-Z]{2,}\b/g) || [];
72
+ topics.push(...allCaps);
73
+ // Also include regular keywords for broader matching
74
+ const keywords = extractKeywords(prompt);
75
+ topics.push(...keywords);
76
+ // Dedupe and filter empty
77
+ return [...new Set(topics)].filter(t => t.length > 1);
78
+ }
79
+ //# sourceMappingURL=keywords.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keywords.js","sourceRoot":"","sources":["../../src/search/keywords.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ export interface CtxPilotConfig {
2
+ pinned: string[];
3
+ include: string[];
4
+ exclude: string[];
5
+ tokenBudget: number;
6
+ maxContextPercentage: number;
7
+ }
8
+ export interface Section {
9
+ title: string;
10
+ lineStart: number;
11
+ lineEnd: number;
12
+ preview: string;
13
+ tokens: number;
14
+ keywords: string[];
15
+ }
16
+ export interface FileIndex {
17
+ path: string;
18
+ mtime: string;
19
+ hash: string;
20
+ sections: Section[];
21
+ }
22
+ export interface ProjectIndex {
23
+ version: string;
24
+ lastUpdated: string;
25
+ files: FileIndex[];
26
+ }
27
+ export interface ScoredSection {
28
+ file: string;
29
+ section: Section;
30
+ score: number;
31
+ }
32
+ export interface SearchOptions {
33
+ maxResults?: number;
34
+ maxTokens?: number;
35
+ }
36
+ export interface IndexOptions {
37
+ force?: boolean;
38
+ }
39
+ export type SectionParser = (content: string, filePath: string) => Section[];
40
+ export interface HookInput {
41
+ prompt: string;
42
+ transcript_path?: string;
43
+ }
44
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAGD,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAGD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAGD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB;AAGD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAGD,MAAM,WAAW,aAAa;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAGD,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAGD,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,EAAE,CAAC;AAG7E,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ export declare function loadGitignorePatterns(projectRoot: string): Promise<string[]>;
2
+ export declare function parseGitignore(content: string): string[];
3
+ export declare function createIgnoreFilter(patterns: string[]): (path: string) => boolean;
4
+ export declare function mergePatterns(gitignorePatterns: string[], excludePatterns: string[]): string[];
5
+ //# sourceMappingURL=gitignore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gitignore.d.ts","sourceRoot":"","sources":["../../src/utils/gitignore.ts"],"names":[],"mappings":"AAMA,wBAAsB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAUlF;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAKxD;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAGhF;AAED,wBAAgB,aAAa,CAC3B,iBAAiB,EAAE,MAAM,EAAE,EAC3B,eAAe,EAAE,MAAM,EAAE,GACxB,MAAM,EAAE,CAIV"}
@@ -0,0 +1,31 @@
1
+ import { readFile } from 'fs/promises';
2
+ import { join } from 'path';
3
+ import ignoreModule from 'ignore';
4
+ const ignore = ignoreModule.default || ignoreModule;
5
+ export async function loadGitignorePatterns(projectRoot) {
6
+ const gitignorePath = join(projectRoot, '.gitignore');
7
+ try {
8
+ const content = await readFile(gitignorePath, 'utf-8');
9
+ return parseGitignore(content);
10
+ }
11
+ catch {
12
+ // No .gitignore file, return empty patterns
13
+ return [];
14
+ }
15
+ }
16
+ export function parseGitignore(content) {
17
+ return content
18
+ .split('\n')
19
+ .map(line => line.trim())
20
+ .filter(line => line && !line.startsWith('#'));
21
+ }
22
+ export function createIgnoreFilter(patterns) {
23
+ const ig = ignore().add(patterns);
24
+ return (path) => ig.ignores(path);
25
+ }
26
+ export function mergePatterns(gitignorePatterns, excludePatterns) {
27
+ // Combine patterns, removing duplicates
28
+ const combined = new Set([...gitignorePatterns, ...excludePatterns]);
29
+ return Array.from(combined);
30
+ }
31
+ //# sourceMappingURL=gitignore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gitignore.js","sourceRoot":"","sources":["../../src/utils/gitignore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,YAAY,MAAM,QAAQ,CAAC;AAElC,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,IAAI,YAAY,CAAC;AAEpD,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,WAAmB;IAC7D,MAAM,aAAa,GAAG,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IAEtD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QACvD,OAAO,cAAc,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,4CAA4C;QAC5C,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,OAAO,OAAO;SACX,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SACxB,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,QAAkB;IACnD,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAClC,OAAO,CAAC,IAAY,EAAE,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,iBAA2B,EAC3B,eAAyB;IAEzB,wCAAwC;IACxC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,iBAAiB,EAAE,GAAG,eAAe,CAAC,CAAC,CAAC;IACrE,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './gitignore.js';
2
+ export * from './paths.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './gitignore.js';
2
+ export * from './paths.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC"}
@@ -0,0 +1,8 @@
1
+ export declare function toRelativePath(projectRoot: string, absolutePath: string): string;
2
+ export declare function toAbsolutePath(projectRoot: string, relativePath: string): string;
3
+ export declare function getExtension(filePath: string): string;
4
+ export declare function normalizeSlashes(path: string): string;
5
+ export declare function getIndexPath(projectRoot: string): string;
6
+ export declare function getClaudeMdPath(projectRoot: string): string;
7
+ export declare function getClaudeSettingsPath(projectRoot: string): string;
8
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAEA,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAEhF;AAED,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAEhF;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEjE"}
@@ -0,0 +1,23 @@
1
+ import { join, relative, resolve, extname } from 'path';
2
+ export function toRelativePath(projectRoot, absolutePath) {
3
+ return relative(projectRoot, absolutePath).replace(/\\/g, '/');
4
+ }
5
+ export function toAbsolutePath(projectRoot, relativePath) {
6
+ return resolve(projectRoot, relativePath);
7
+ }
8
+ export function getExtension(filePath) {
9
+ return extname(filePath).toLowerCase();
10
+ }
11
+ export function normalizeSlashes(path) {
12
+ return path.replace(/\\/g, '/');
13
+ }
14
+ export function getIndexPath(projectRoot) {
15
+ return join(projectRoot, '.context', 'index.json');
16
+ }
17
+ export function getClaudeMdPath(projectRoot) {
18
+ return join(projectRoot, 'CLAUDE.md');
19
+ }
20
+ export function getClaudeSettingsPath(projectRoot) {
21
+ return join(projectRoot, '.claude', 'settings.json');
22
+ }
23
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAExD,MAAM,UAAU,cAAc,CAAC,WAAmB,EAAE,YAAoB;IACtE,OAAO,QAAQ,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,WAAmB,EAAE,YAAoB;IACtE,OAAO,OAAO,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,QAAgB;IAC3C,OAAO,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,WAAmB;IAC9C,OAAO,IAAI,CAAC,WAAW,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,WAAmB;IACjD,OAAO,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,WAAmB;IACvD,OAAO,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;AACvD,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function estimateTokens(text: string): number;
2
+ export declare function truncateToTokens(text: string, maxTokens: number): string;
3
+ //# sourceMappingURL=tokens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/utils/tokens.ts"],"names":[],"mappings":"AAGA,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGnD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAiBxE"}
@@ -0,0 +1,22 @@
1
+ // Simple token estimation using chars/4 approximation
2
+ // This is a rough estimate, not exact tokenization
3
+ export function estimateTokens(text) {
4
+ if (!text)
5
+ return 0;
6
+ return Math.ceil(text.length / 4);
7
+ }
8
+ export function truncateToTokens(text, maxTokens) {
9
+ const maxChars = maxTokens * 4;
10
+ if (text.length <= maxChars) {
11
+ return text;
12
+ }
13
+ // Try to truncate at a word boundary
14
+ const truncated = text.slice(0, maxChars);
15
+ const lastSpace = truncated.lastIndexOf(' ');
16
+ // If we found a space in the last 20% of the text, use it
17
+ if (lastSpace > maxChars * 0.8) {
18
+ return truncated.slice(0, lastSpace) + '...';
19
+ }
20
+ return truncated + '...';
21
+ }
22
+ //# sourceMappingURL=tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../src/utils/tokens.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,mDAAmD;AAEnD,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,IAAI,CAAC,IAAI;QAAE,OAAO,CAAC,CAAC;IACpB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,SAAiB;IAC9D,MAAM,QAAQ,GAAG,SAAS,GAAG,CAAC,CAAC;IAE/B,IAAI,IAAI,CAAC,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,qCAAqC;IACrC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC1C,MAAM,SAAS,GAAG,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAE7C,0DAA0D;IAC1D,IAAI,SAAS,GAAG,QAAQ,GAAG,GAAG,EAAE,CAAC;QAC/B,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC;IAC/C,CAAC;IAED,OAAO,SAAS,GAAG,KAAK,CAAC;AAC3B,CAAC"}
package/package.json ADDED
@@ -0,0 +1,77 @@
1
+ {
2
+ "name": "ctx-pilot",
3
+ "version": "0.9.0",
4
+ "description": "Stop repeating yourself to AI. Auto-suggests relevant files before every prompt. Works with Claude Code, Gemini CLI, Cursor, Windsurf, and Aider.",
5
+ "type": "module",
6
+ "main": "dist/cli.js",
7
+ "types": "dist/cli.d.ts",
8
+ "bin": {
9
+ "ctx-pilot": "dist/cli.js"
10
+ },
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/cli.d.ts",
14
+ "import": "./dist/cli.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "LICENSE",
20
+ "LICENSE-COMMERCIAL",
21
+ "README.md"
22
+ ],
23
+ "scripts": {
24
+ "build": "tsc",
25
+ "dev": "tsc --watch",
26
+ "test": "vitest",
27
+ "test:run": "vitest run",
28
+ "lint": "eslint src/",
29
+ "prepublishOnly": "npm run build && npm run test:run"
30
+ },
31
+ "keywords": [
32
+ "claude",
33
+ "claude-code",
34
+ "gemini",
35
+ "gemini-cli",
36
+ "cursor",
37
+ "windsurf",
38
+ "aider",
39
+ "context",
40
+ "ai",
41
+ "llm",
42
+ "coding-assistant",
43
+ "hook"
44
+ ],
45
+ "author": {
46
+ "name": "Stephen Gobin",
47
+ "url": "https://github.com/stephen-gobin"
48
+ },
49
+ "repository": {
50
+ "type": "git",
51
+ "url": "git+https://github.com/Suite110/ctx-pilot.git"
52
+ },
53
+ "homepage": "https://github.com/Suite110/ctx-pilot#readme",
54
+ "bugs": {
55
+ "url": "https://github.com/Suite110/ctx-pilot/issues"
56
+ },
57
+ "license": "MIT",
58
+ "dependencies": {
59
+ "chokidar": "^5.0.0",
60
+ "fast-glob": "^3.3.0",
61
+ "ignore": "^5.3.0",
62
+ "zod": "^3.23.0"
63
+ },
64
+ "devDependencies": {
65
+ "@types/node": "^20.0.0",
66
+ "typescript": "^5.3.0",
67
+ "vitest": "^1.0.0"
68
+ },
69
+ "engines": {
70
+ "node": ">=18.0.0"
71
+ },
72
+ "os": [
73
+ "darwin",
74
+ "linux",
75
+ "win32"
76
+ ]
77
+ }