@compilr-dev/agents 0.0.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.
- package/README.md +1277 -0
- package/dist/agent.d.ts +1272 -0
- package/dist/agent.js +1912 -0
- package/dist/anchors/builtin.d.ts +24 -0
- package/dist/anchors/builtin.js +61 -0
- package/dist/anchors/index.d.ts +6 -0
- package/dist/anchors/index.js +5 -0
- package/dist/anchors/manager.d.ts +115 -0
- package/dist/anchors/manager.js +412 -0
- package/dist/anchors/types.d.ts +168 -0
- package/dist/anchors/types.js +10 -0
- package/dist/context/index.d.ts +12 -0
- package/dist/context/index.js +10 -0
- package/dist/context/manager.d.ts +224 -0
- package/dist/context/manager.js +770 -0
- package/dist/context/types.d.ts +377 -0
- package/dist/context/types.js +7 -0
- package/dist/costs/index.d.ts +8 -0
- package/dist/costs/index.js +7 -0
- package/dist/costs/tracker.d.ts +121 -0
- package/dist/costs/tracker.js +295 -0
- package/dist/costs/types.d.ts +157 -0
- package/dist/costs/types.js +8 -0
- package/dist/errors.d.ts +178 -0
- package/dist/errors.js +249 -0
- package/dist/guardrails/builtin.d.ts +27 -0
- package/dist/guardrails/builtin.js +223 -0
- package/dist/guardrails/index.d.ts +6 -0
- package/dist/guardrails/index.js +5 -0
- package/dist/guardrails/manager.d.ts +117 -0
- package/dist/guardrails/manager.js +288 -0
- package/dist/guardrails/types.d.ts +159 -0
- package/dist/guardrails/types.js +7 -0
- package/dist/hooks/index.d.ts +31 -0
- package/dist/hooks/index.js +29 -0
- package/dist/hooks/manager.d.ts +147 -0
- package/dist/hooks/manager.js +600 -0
- package/dist/hooks/types.d.ts +368 -0
- package/dist/hooks/types.js +12 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.js +73 -0
- package/dist/mcp/client.d.ts +93 -0
- package/dist/mcp/client.js +287 -0
- package/dist/mcp/errors.d.ts +60 -0
- package/dist/mcp/errors.js +78 -0
- package/dist/mcp/index.d.ts +43 -0
- package/dist/mcp/index.js +45 -0
- package/dist/mcp/manager.d.ts +120 -0
- package/dist/mcp/manager.js +276 -0
- package/dist/mcp/tools.d.ts +54 -0
- package/dist/mcp/tools.js +99 -0
- package/dist/mcp/types.d.ts +150 -0
- package/dist/mcp/types.js +40 -0
- package/dist/memory/index.d.ts +8 -0
- package/dist/memory/index.js +7 -0
- package/dist/memory/loader.d.ts +114 -0
- package/dist/memory/loader.js +463 -0
- package/dist/memory/types.d.ts +182 -0
- package/dist/memory/types.js +8 -0
- package/dist/messages/index.d.ts +82 -0
- package/dist/messages/index.js +155 -0
- package/dist/permissions/index.d.ts +5 -0
- package/dist/permissions/index.js +4 -0
- package/dist/permissions/manager.d.ts +125 -0
- package/dist/permissions/manager.js +379 -0
- package/dist/permissions/types.d.ts +162 -0
- package/dist/permissions/types.js +7 -0
- package/dist/providers/claude.d.ts +90 -0
- package/dist/providers/claude.js +348 -0
- package/dist/providers/index.d.ts +8 -0
- package/dist/providers/index.js +11 -0
- package/dist/providers/mock.d.ts +133 -0
- package/dist/providers/mock.js +204 -0
- package/dist/providers/types.d.ts +168 -0
- package/dist/providers/types.js +4 -0
- package/dist/rate-limit/index.d.ts +45 -0
- package/dist/rate-limit/index.js +47 -0
- package/dist/rate-limit/limiter.d.ts +104 -0
- package/dist/rate-limit/limiter.js +326 -0
- package/dist/rate-limit/provider-wrapper.d.ts +112 -0
- package/dist/rate-limit/provider-wrapper.js +201 -0
- package/dist/rate-limit/retry.d.ts +108 -0
- package/dist/rate-limit/retry.js +287 -0
- package/dist/rate-limit/types.d.ts +181 -0
- package/dist/rate-limit/types.js +22 -0
- package/dist/rehearsal/file-analyzer.d.ts +22 -0
- package/dist/rehearsal/file-analyzer.js +351 -0
- package/dist/rehearsal/git-analyzer.d.ts +22 -0
- package/dist/rehearsal/git-analyzer.js +472 -0
- package/dist/rehearsal/index.d.ts +35 -0
- package/dist/rehearsal/index.js +36 -0
- package/dist/rehearsal/manager.d.ts +100 -0
- package/dist/rehearsal/manager.js +290 -0
- package/dist/rehearsal/types.d.ts +235 -0
- package/dist/rehearsal/types.js +8 -0
- package/dist/skills/index.d.ts +160 -0
- package/dist/skills/index.js +282 -0
- package/dist/state/agent-state.d.ts +41 -0
- package/dist/state/agent-state.js +88 -0
- package/dist/state/checkpointer.d.ts +110 -0
- package/dist/state/checkpointer.js +362 -0
- package/dist/state/errors.d.ts +66 -0
- package/dist/state/errors.js +88 -0
- package/dist/state/index.d.ts +35 -0
- package/dist/state/index.js +37 -0
- package/dist/state/serializer.d.ts +55 -0
- package/dist/state/serializer.js +172 -0
- package/dist/state/types.d.ts +312 -0
- package/dist/state/types.js +14 -0
- package/dist/tools/builtin/bash-output.d.ts +61 -0
- package/dist/tools/builtin/bash-output.js +90 -0
- package/dist/tools/builtin/bash.d.ts +150 -0
- package/dist/tools/builtin/bash.js +354 -0
- package/dist/tools/builtin/edit.d.ts +50 -0
- package/dist/tools/builtin/edit.js +215 -0
- package/dist/tools/builtin/glob.d.ts +62 -0
- package/dist/tools/builtin/glob.js +244 -0
- package/dist/tools/builtin/grep.d.ts +74 -0
- package/dist/tools/builtin/grep.js +363 -0
- package/dist/tools/builtin/index.d.ts +44 -0
- package/dist/tools/builtin/index.js +69 -0
- package/dist/tools/builtin/kill-shell.d.ts +44 -0
- package/dist/tools/builtin/kill-shell.js +80 -0
- package/dist/tools/builtin/read-file.d.ts +57 -0
- package/dist/tools/builtin/read-file.js +184 -0
- package/dist/tools/builtin/shell-manager.d.ts +176 -0
- package/dist/tools/builtin/shell-manager.js +337 -0
- package/dist/tools/builtin/task.d.ts +202 -0
- package/dist/tools/builtin/task.js +350 -0
- package/dist/tools/builtin/todo.d.ts +207 -0
- package/dist/tools/builtin/todo.js +453 -0
- package/dist/tools/builtin/utils.d.ts +27 -0
- package/dist/tools/builtin/utils.js +70 -0
- package/dist/tools/builtin/web-fetch.d.ts +96 -0
- package/dist/tools/builtin/web-fetch.js +290 -0
- package/dist/tools/builtin/write-file.d.ts +54 -0
- package/dist/tools/builtin/write-file.js +147 -0
- package/dist/tools/define.d.ts +60 -0
- package/dist/tools/define.js +65 -0
- package/dist/tools/index.d.ts +10 -0
- package/dist/tools/index.js +37 -0
- package/dist/tools/registry.d.ts +79 -0
- package/dist/tools/registry.js +151 -0
- package/dist/tools/types.d.ts +59 -0
- package/dist/tools/types.js +4 -0
- package/dist/tracing/hooks.d.ts +58 -0
- package/dist/tracing/hooks.js +377 -0
- package/dist/tracing/index.d.ts +51 -0
- package/dist/tracing/index.js +55 -0
- package/dist/tracing/logging.d.ts +78 -0
- package/dist/tracing/logging.js +310 -0
- package/dist/tracing/manager.d.ts +160 -0
- package/dist/tracing/manager.js +468 -0
- package/dist/tracing/otel.d.ts +102 -0
- package/dist/tracing/otel.js +246 -0
- package/dist/tracing/types.d.ts +346 -0
- package/dist/tracing/types.js +38 -0
- package/dist/utils/index.d.ts +23 -0
- package/dist/utils/index.js +44 -0
- package/package.json +79 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProjectMemoryLoader - Loads project-level instructions from markdown files
|
|
3
|
+
*
|
|
4
|
+
* Supports various LLM-specific naming conventions:
|
|
5
|
+
* - CLAUDE.md, .claude.md, .claude/instructions.md (Claude/Anthropic)
|
|
6
|
+
* - GEMINI.md, .gemini.md, .gemini/instructions.md (Google Gemini)
|
|
7
|
+
* - COPILOT.md, .github/copilot-instructions.md (GitHub Copilot)
|
|
8
|
+
* - GPT.md, OPENAI.md (OpenAI)
|
|
9
|
+
* - CURSOR.md, .cursor/rules (Cursor)
|
|
10
|
+
* - CODEIUM.md (Codeium)
|
|
11
|
+
*
|
|
12
|
+
* Also supports generic names:
|
|
13
|
+
* - PROJECT.md, INSTRUCTIONS.md, AI.md, CONTEXT.md
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const loader = new ProjectMemoryLoader({
|
|
18
|
+
* providers: ['claude', 'gemini'],
|
|
19
|
+
* includeGeneric: true,
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* const memory = await loader.load('/path/to/project');
|
|
23
|
+
* console.log(memory.content); // Combined instructions
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
import type { LLMProviderName, ProjectMemory, FilePattern, ProjectMemoryOptions, ProjectMemoryEventHandler, MemoryDiscoveryResult, ProviderPatterns } from './types.js';
|
|
27
|
+
/**
|
|
28
|
+
* Built-in patterns for various LLM providers
|
|
29
|
+
*/
|
|
30
|
+
declare const PROVIDER_PATTERNS: ProviderPatterns[];
|
|
31
|
+
/**
|
|
32
|
+
* Generic patterns that apply to any LLM
|
|
33
|
+
*/
|
|
34
|
+
declare const GENERIC_PATTERNS: FilePattern[];
|
|
35
|
+
/**
|
|
36
|
+
* ProjectMemoryLoader discovers and loads project-specific instructions
|
|
37
|
+
*/
|
|
38
|
+
export declare class ProjectMemoryLoader {
|
|
39
|
+
private readonly options;
|
|
40
|
+
private readonly patterns;
|
|
41
|
+
private readonly eventHandlers;
|
|
42
|
+
constructor(options?: ProjectMemoryOptions);
|
|
43
|
+
/**
|
|
44
|
+
* Build the list of patterns to search for
|
|
45
|
+
*/
|
|
46
|
+
private buildPatterns;
|
|
47
|
+
/**
|
|
48
|
+
* Load project memory from a directory
|
|
49
|
+
*
|
|
50
|
+
* @param rootDir - Starting directory for search
|
|
51
|
+
* @returns Loaded project memory
|
|
52
|
+
*/
|
|
53
|
+
load(rootDir: string): Promise<ProjectMemory>;
|
|
54
|
+
/**
|
|
55
|
+
* Discover memory files without loading content
|
|
56
|
+
*
|
|
57
|
+
* @param rootDir - Starting directory for search
|
|
58
|
+
* @returns Discovery result with paths
|
|
59
|
+
*/
|
|
60
|
+
discover(rootDir: string): Promise<MemoryDiscoveryResult>;
|
|
61
|
+
/**
|
|
62
|
+
* Get the list of directories to search
|
|
63
|
+
*/
|
|
64
|
+
private getSearchDirectories;
|
|
65
|
+
/**
|
|
66
|
+
* Combine content from multiple files
|
|
67
|
+
*/
|
|
68
|
+
private combineContent;
|
|
69
|
+
/**
|
|
70
|
+
* Format the header for a file
|
|
71
|
+
*/
|
|
72
|
+
private formatHeader;
|
|
73
|
+
/**
|
|
74
|
+
* Register an event handler
|
|
75
|
+
*/
|
|
76
|
+
onEvent(handler: ProjectMemoryEventHandler): () => void;
|
|
77
|
+
/**
|
|
78
|
+
* Emit an event
|
|
79
|
+
*/
|
|
80
|
+
private emit;
|
|
81
|
+
/**
|
|
82
|
+
* Get the patterns being used
|
|
83
|
+
*/
|
|
84
|
+
getPatterns(): FilePattern[];
|
|
85
|
+
/**
|
|
86
|
+
* Get the configured options
|
|
87
|
+
*/
|
|
88
|
+
getOptions(): Required<ProjectMemoryOptions>;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Create a ProjectMemoryLoader with default options
|
|
92
|
+
*/
|
|
93
|
+
export declare function createProjectMemoryLoader(options?: ProjectMemoryOptions): ProjectMemoryLoader;
|
|
94
|
+
/**
|
|
95
|
+
* Quick utility to load project memory
|
|
96
|
+
*/
|
|
97
|
+
export declare function loadProjectMemory(rootDir: string, options?: ProjectMemoryOptions): Promise<ProjectMemory>;
|
|
98
|
+
/**
|
|
99
|
+
* Quick utility to check if a directory has project memory files
|
|
100
|
+
*/
|
|
101
|
+
export declare function hasProjectMemory(rootDir: string, options?: ProjectMemoryOptions): Promise<boolean>;
|
|
102
|
+
/**
|
|
103
|
+
* Get built-in patterns for a provider
|
|
104
|
+
*/
|
|
105
|
+
export declare function getProviderPatterns(provider: LLMProviderName): FilePattern[];
|
|
106
|
+
/**
|
|
107
|
+
* Get all supported provider names
|
|
108
|
+
*/
|
|
109
|
+
export declare function getSupportedProviders(): LLMProviderName[];
|
|
110
|
+
/**
|
|
111
|
+
* Get generic patterns
|
|
112
|
+
*/
|
|
113
|
+
export declare function getGenericPatterns(): FilePattern[];
|
|
114
|
+
export { PROVIDER_PATTERNS, GENERIC_PATTERNS };
|
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProjectMemoryLoader - Loads project-level instructions from markdown files
|
|
3
|
+
*
|
|
4
|
+
* Supports various LLM-specific naming conventions:
|
|
5
|
+
* - CLAUDE.md, .claude.md, .claude/instructions.md (Claude/Anthropic)
|
|
6
|
+
* - GEMINI.md, .gemini.md, .gemini/instructions.md (Google Gemini)
|
|
7
|
+
* - COPILOT.md, .github/copilot-instructions.md (GitHub Copilot)
|
|
8
|
+
* - GPT.md, OPENAI.md (OpenAI)
|
|
9
|
+
* - CURSOR.md, .cursor/rules (Cursor)
|
|
10
|
+
* - CODEIUM.md (Codeium)
|
|
11
|
+
*
|
|
12
|
+
* Also supports generic names:
|
|
13
|
+
* - PROJECT.md, INSTRUCTIONS.md, AI.md, CONTEXT.md
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const loader = new ProjectMemoryLoader({
|
|
18
|
+
* providers: ['claude', 'gemini'],
|
|
19
|
+
* includeGeneric: true,
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* const memory = await loader.load('/path/to/project');
|
|
23
|
+
* console.log(memory.content); // Combined instructions
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
import * as fs from 'fs/promises';
|
|
27
|
+
import * as path from 'path';
|
|
28
|
+
/**
|
|
29
|
+
* Built-in patterns for various LLM providers
|
|
30
|
+
*/
|
|
31
|
+
const PROVIDER_PATTERNS = [
|
|
32
|
+
{
|
|
33
|
+
provider: 'claude',
|
|
34
|
+
patterns: [
|
|
35
|
+
{ pattern: 'CLAUDE.md', priority: 1, description: 'Claude project instructions' },
|
|
36
|
+
{ pattern: '.claude.md', priority: 2, description: 'Hidden Claude instructions' },
|
|
37
|
+
{
|
|
38
|
+
pattern: '.claude/instructions.md',
|
|
39
|
+
priority: 3,
|
|
40
|
+
description: 'Claude directory instructions',
|
|
41
|
+
},
|
|
42
|
+
{ pattern: '.claude/CLAUDE.md', priority: 4, description: 'Claude directory main file' },
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
provider: 'anthropic',
|
|
47
|
+
patterns: [
|
|
48
|
+
{ pattern: 'ANTHROPIC.md', priority: 1, description: 'Anthropic project instructions' },
|
|
49
|
+
{ pattern: '.anthropic.md', priority: 2, description: 'Hidden Anthropic instructions' },
|
|
50
|
+
{
|
|
51
|
+
pattern: '.anthropic/instructions.md',
|
|
52
|
+
priority: 3,
|
|
53
|
+
description: 'Anthropic directory instructions',
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
provider: 'gemini',
|
|
59
|
+
patterns: [
|
|
60
|
+
{ pattern: 'GEMINI.md', priority: 1, description: 'Gemini project instructions' },
|
|
61
|
+
{ pattern: '.gemini.md', priority: 2, description: 'Hidden Gemini instructions' },
|
|
62
|
+
{
|
|
63
|
+
pattern: '.gemini/instructions.md',
|
|
64
|
+
priority: 3,
|
|
65
|
+
description: 'Gemini directory instructions',
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
provider: 'openai',
|
|
71
|
+
patterns: [
|
|
72
|
+
{ pattern: 'OPENAI.md', priority: 1, description: 'OpenAI project instructions' },
|
|
73
|
+
{ pattern: '.openai.md', priority: 2, description: 'Hidden OpenAI instructions' },
|
|
74
|
+
{
|
|
75
|
+
pattern: '.openai/instructions.md',
|
|
76
|
+
priority: 3,
|
|
77
|
+
description: 'OpenAI directory instructions',
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
provider: 'gpt',
|
|
83
|
+
patterns: [
|
|
84
|
+
{ pattern: 'GPT.md', priority: 1, description: 'GPT project instructions' },
|
|
85
|
+
{ pattern: '.gpt.md', priority: 2, description: 'Hidden GPT instructions' },
|
|
86
|
+
{ pattern: 'CHATGPT.md', priority: 3, description: 'ChatGPT instructions' },
|
|
87
|
+
],
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
provider: 'copilot',
|
|
91
|
+
patterns: [
|
|
92
|
+
{ pattern: 'COPILOT.md', priority: 1, description: 'Copilot project instructions' },
|
|
93
|
+
{ pattern: '.copilot.md', priority: 2, description: 'Hidden Copilot instructions' },
|
|
94
|
+
{
|
|
95
|
+
pattern: '.github/copilot-instructions.md',
|
|
96
|
+
priority: 3,
|
|
97
|
+
description: 'GitHub Copilot instructions',
|
|
98
|
+
},
|
|
99
|
+
],
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
provider: 'cursor',
|
|
103
|
+
patterns: [
|
|
104
|
+
{ pattern: 'CURSOR.md', priority: 1, description: 'Cursor project instructions' },
|
|
105
|
+
{ pattern: '.cursor.md', priority: 2, description: 'Hidden Cursor instructions' },
|
|
106
|
+
{ pattern: '.cursor/rules', priority: 3, description: 'Cursor rules file' },
|
|
107
|
+
{ pattern: '.cursorrules', priority: 4, description: 'Cursor rules (alt location)' },
|
|
108
|
+
],
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
provider: 'codeium',
|
|
112
|
+
patterns: [
|
|
113
|
+
{ pattern: 'CODEIUM.md', priority: 1, description: 'Codeium project instructions' },
|
|
114
|
+
{ pattern: '.codeium.md', priority: 2, description: 'Hidden Codeium instructions' },
|
|
115
|
+
{
|
|
116
|
+
pattern: '.codeium/instructions.md',
|
|
117
|
+
priority: 3,
|
|
118
|
+
description: 'Codeium directory instructions',
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
},
|
|
122
|
+
];
|
|
123
|
+
/**
|
|
124
|
+
* Generic patterns that apply to any LLM
|
|
125
|
+
*/
|
|
126
|
+
const GENERIC_PATTERNS = [
|
|
127
|
+
{ pattern: 'PROJECT.md', priority: 10, description: 'Generic project instructions' },
|
|
128
|
+
{ pattern: 'INSTRUCTIONS.md', priority: 11, description: 'Generic instructions' },
|
|
129
|
+
{ pattern: 'AI.md', priority: 12, description: 'AI-specific instructions' },
|
|
130
|
+
{ pattern: 'CONTEXT.md', priority: 13, description: 'Project context' },
|
|
131
|
+
{ pattern: '.ai/instructions.md', priority: 14, description: 'AI directory instructions' },
|
|
132
|
+
{ pattern: '.instructions.md', priority: 15, description: 'Hidden instructions' },
|
|
133
|
+
];
|
|
134
|
+
/**
|
|
135
|
+
* Default options for ProjectMemoryLoader
|
|
136
|
+
*/
|
|
137
|
+
const DEFAULT_OPTIONS = {
|
|
138
|
+
providers: 'claude',
|
|
139
|
+
includeGeneric: true,
|
|
140
|
+
customPatterns: [],
|
|
141
|
+
searchParents: true,
|
|
142
|
+
maxParentDepth: 10,
|
|
143
|
+
stopAtGitRoot: true,
|
|
144
|
+
combineStrategy: 'concat',
|
|
145
|
+
separator: '\n\n---\n\n',
|
|
146
|
+
maxContentSize: 100000,
|
|
147
|
+
includeHeaders: true,
|
|
148
|
+
headerFormat: '# From: {relativePath}\n\n',
|
|
149
|
+
encoding: 'utf-8',
|
|
150
|
+
};
|
|
151
|
+
/**
|
|
152
|
+
* ProjectMemoryLoader discovers and loads project-specific instructions
|
|
153
|
+
*/
|
|
154
|
+
export class ProjectMemoryLoader {
|
|
155
|
+
options;
|
|
156
|
+
patterns;
|
|
157
|
+
eventHandlers = new Set();
|
|
158
|
+
constructor(options = {}) {
|
|
159
|
+
this.options = { ...DEFAULT_OPTIONS, ...options };
|
|
160
|
+
// Build pattern list
|
|
161
|
+
this.patterns = this.buildPatterns();
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Build the list of patterns to search for
|
|
165
|
+
*/
|
|
166
|
+
buildPatterns() {
|
|
167
|
+
const patterns = [];
|
|
168
|
+
// Add provider-specific patterns
|
|
169
|
+
const providers = Array.isArray(this.options.providers)
|
|
170
|
+
? this.options.providers
|
|
171
|
+
: [this.options.providers];
|
|
172
|
+
for (const provider of providers) {
|
|
173
|
+
const providerPatterns = PROVIDER_PATTERNS.find((p) => p.provider.toLowerCase() === provider.toLowerCase());
|
|
174
|
+
if (providerPatterns) {
|
|
175
|
+
patterns.push(...providerPatterns.patterns);
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
// Unknown provider - generate standard patterns
|
|
179
|
+
const name = provider.toUpperCase();
|
|
180
|
+
const lower = provider.toLowerCase();
|
|
181
|
+
patterns.push({ pattern: `${name}.md`, priority: 1, description: `${name} project instructions` }, { pattern: `.${lower}.md`, priority: 2, description: `Hidden ${name} instructions` }, {
|
|
182
|
+
pattern: `.${lower}/instructions.md`,
|
|
183
|
+
priority: 3,
|
|
184
|
+
description: `${name} directory instructions`,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// Add generic patterns if enabled
|
|
189
|
+
if (this.options.includeGeneric) {
|
|
190
|
+
patterns.push(...GENERIC_PATTERNS);
|
|
191
|
+
}
|
|
192
|
+
// Add custom patterns
|
|
193
|
+
if (this.options.customPatterns.length > 0) {
|
|
194
|
+
patterns.push(...this.options.customPatterns);
|
|
195
|
+
}
|
|
196
|
+
// Sort by priority
|
|
197
|
+
return patterns.sort((a, b) => a.priority - b.priority);
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Load project memory from a directory
|
|
201
|
+
*
|
|
202
|
+
* @param rootDir - Starting directory for search
|
|
203
|
+
* @returns Loaded project memory
|
|
204
|
+
*/
|
|
205
|
+
async load(rootDir) {
|
|
206
|
+
const absoluteRoot = path.resolve(rootDir);
|
|
207
|
+
this.emit({
|
|
208
|
+
type: 'memory:search_start',
|
|
209
|
+
rootDir: absoluteRoot,
|
|
210
|
+
patterns: this.patterns.map((p) => p.pattern),
|
|
211
|
+
});
|
|
212
|
+
const files = [];
|
|
213
|
+
let totalSize = 0;
|
|
214
|
+
// Get directories to search
|
|
215
|
+
const directories = await this.getSearchDirectories(absoluteRoot);
|
|
216
|
+
// Search each directory
|
|
217
|
+
for (const dir of directories) {
|
|
218
|
+
for (const pattern of this.patterns) {
|
|
219
|
+
// Check size limit
|
|
220
|
+
if (totalSize >= this.options.maxContentSize) {
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
223
|
+
const filePath = path.join(dir, pattern.pattern);
|
|
224
|
+
try {
|
|
225
|
+
const stat = await fs.stat(filePath);
|
|
226
|
+
if (stat.isFile()) {
|
|
227
|
+
this.emit({ type: 'memory:file_found', path: filePath, pattern: pattern.pattern });
|
|
228
|
+
// Check if adding this file would exceed limit
|
|
229
|
+
if (totalSize + stat.size > this.options.maxContentSize) {
|
|
230
|
+
this.emit({
|
|
231
|
+
type: 'memory:file_skipped',
|
|
232
|
+
path: filePath,
|
|
233
|
+
reason: 'Would exceed max content size',
|
|
234
|
+
});
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
// Load file content
|
|
238
|
+
const content = await fs.readFile(filePath, this.options.encoding);
|
|
239
|
+
const memoryFile = {
|
|
240
|
+
path: filePath,
|
|
241
|
+
content,
|
|
242
|
+
relativePath: path.relative(absoluteRoot, filePath),
|
|
243
|
+
matchedPattern: pattern.pattern,
|
|
244
|
+
size: stat.size,
|
|
245
|
+
modifiedAt: stat.mtime,
|
|
246
|
+
};
|
|
247
|
+
files.push(memoryFile);
|
|
248
|
+
totalSize += stat.size;
|
|
249
|
+
this.emit({ type: 'memory:file_loaded', file: memoryFile });
|
|
250
|
+
// For 'priority' strategy, stop after first file
|
|
251
|
+
if (this.options.combineStrategy === 'priority') {
|
|
252
|
+
break;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
catch {
|
|
257
|
+
// File doesn't exist, continue
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
// For 'priority' strategy, stop after first file found
|
|
261
|
+
if (this.options.combineStrategy === 'priority' && files.length > 0) {
|
|
262
|
+
break;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
// Combine content
|
|
266
|
+
const content = this.combineContent(files, absoluteRoot);
|
|
267
|
+
const memory = {
|
|
268
|
+
files,
|
|
269
|
+
content,
|
|
270
|
+
rootDir: absoluteRoot,
|
|
271
|
+
estimatedTokens: Math.ceil(content.length / 4),
|
|
272
|
+
};
|
|
273
|
+
this.emit({ type: 'memory:search_complete', memory });
|
|
274
|
+
return memory;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Discover memory files without loading content
|
|
278
|
+
*
|
|
279
|
+
* @param rootDir - Starting directory for search
|
|
280
|
+
* @returns Discovery result with paths
|
|
281
|
+
*/
|
|
282
|
+
async discover(rootDir) {
|
|
283
|
+
const absoluteRoot = path.resolve(rootDir);
|
|
284
|
+
const paths = [];
|
|
285
|
+
const matchedPatterns = [];
|
|
286
|
+
const directories = await this.getSearchDirectories(absoluteRoot);
|
|
287
|
+
for (const dir of directories) {
|
|
288
|
+
for (const pattern of this.patterns) {
|
|
289
|
+
const filePath = path.join(dir, pattern.pattern);
|
|
290
|
+
try {
|
|
291
|
+
const stat = await fs.stat(filePath);
|
|
292
|
+
if (stat.isFile()) {
|
|
293
|
+
paths.push(filePath);
|
|
294
|
+
if (!matchedPatterns.includes(pattern.pattern)) {
|
|
295
|
+
matchedPatterns.push(pattern.pattern);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
catch {
|
|
300
|
+
// File doesn't exist
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return {
|
|
305
|
+
paths,
|
|
306
|
+
found: paths.length > 0,
|
|
307
|
+
matchedPatterns,
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Get the list of directories to search
|
|
312
|
+
*/
|
|
313
|
+
async getSearchDirectories(rootDir) {
|
|
314
|
+
const directories = [rootDir];
|
|
315
|
+
if (!this.options.searchParents) {
|
|
316
|
+
return directories;
|
|
317
|
+
}
|
|
318
|
+
let currentDir = rootDir;
|
|
319
|
+
let depth = 0;
|
|
320
|
+
while (depth < this.options.maxParentDepth) {
|
|
321
|
+
const parentDir = path.dirname(currentDir);
|
|
322
|
+
// Stop if we've reached the filesystem root
|
|
323
|
+
if (parentDir === currentDir) {
|
|
324
|
+
break;
|
|
325
|
+
}
|
|
326
|
+
// Check for git root if configured
|
|
327
|
+
if (this.options.stopAtGitRoot) {
|
|
328
|
+
try {
|
|
329
|
+
await fs.access(path.join(currentDir, '.git'));
|
|
330
|
+
// Found git root, don't search beyond
|
|
331
|
+
break;
|
|
332
|
+
}
|
|
333
|
+
catch {
|
|
334
|
+
// Not a git root, continue
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
directories.push(parentDir);
|
|
338
|
+
currentDir = parentDir;
|
|
339
|
+
depth++;
|
|
340
|
+
}
|
|
341
|
+
return directories;
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Combine content from multiple files
|
|
345
|
+
*/
|
|
346
|
+
combineContent(files, rootDir) {
|
|
347
|
+
if (files.length === 0) {
|
|
348
|
+
return '';
|
|
349
|
+
}
|
|
350
|
+
if (this.options.combineStrategy === 'priority') {
|
|
351
|
+
// Just return first file's content
|
|
352
|
+
const file = files[0];
|
|
353
|
+
if (this.options.includeHeaders) {
|
|
354
|
+
const header = this.formatHeader(file, rootDir);
|
|
355
|
+
return header + file.content;
|
|
356
|
+
}
|
|
357
|
+
return file.content;
|
|
358
|
+
}
|
|
359
|
+
// For 'concat' and 'dedupe' strategies
|
|
360
|
+
const parts = [];
|
|
361
|
+
const seenContent = new Set();
|
|
362
|
+
for (const file of files) {
|
|
363
|
+
// Skip duplicates for 'dedupe' strategy
|
|
364
|
+
if (this.options.combineStrategy === 'dedupe') {
|
|
365
|
+
const normalized = file.content.trim();
|
|
366
|
+
if (seenContent.has(normalized)) {
|
|
367
|
+
continue;
|
|
368
|
+
}
|
|
369
|
+
seenContent.add(normalized);
|
|
370
|
+
}
|
|
371
|
+
if (this.options.includeHeaders) {
|
|
372
|
+
const header = this.formatHeader(file, rootDir);
|
|
373
|
+
parts.push(header + file.content);
|
|
374
|
+
}
|
|
375
|
+
else {
|
|
376
|
+
parts.push(file.content);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
return parts.join(this.options.separator);
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Format the header for a file
|
|
383
|
+
*/
|
|
384
|
+
formatHeader(file, rootDir) {
|
|
385
|
+
return this.options.headerFormat
|
|
386
|
+
.replace('{path}', file.path)
|
|
387
|
+
.replace('{relativePath}', file.relativePath || path.relative(rootDir, file.path));
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Register an event handler
|
|
391
|
+
*/
|
|
392
|
+
onEvent(handler) {
|
|
393
|
+
this.eventHandlers.add(handler);
|
|
394
|
+
return () => this.eventHandlers.delete(handler);
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Emit an event
|
|
398
|
+
*/
|
|
399
|
+
emit(event) {
|
|
400
|
+
for (const handler of this.eventHandlers) {
|
|
401
|
+
try {
|
|
402
|
+
handler(event);
|
|
403
|
+
}
|
|
404
|
+
catch {
|
|
405
|
+
// Ignore handler errors
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Get the patterns being used
|
|
411
|
+
*/
|
|
412
|
+
getPatterns() {
|
|
413
|
+
return [...this.patterns];
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Get the configured options
|
|
417
|
+
*/
|
|
418
|
+
getOptions() {
|
|
419
|
+
return { ...this.options };
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* Create a ProjectMemoryLoader with default options
|
|
424
|
+
*/
|
|
425
|
+
export function createProjectMemoryLoader(options) {
|
|
426
|
+
return new ProjectMemoryLoader(options);
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Quick utility to load project memory
|
|
430
|
+
*/
|
|
431
|
+
export async function loadProjectMemory(rootDir, options) {
|
|
432
|
+
const loader = new ProjectMemoryLoader(options);
|
|
433
|
+
return loader.load(rootDir);
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Quick utility to check if a directory has project memory files
|
|
437
|
+
*/
|
|
438
|
+
export async function hasProjectMemory(rootDir, options) {
|
|
439
|
+
const loader = new ProjectMemoryLoader(options);
|
|
440
|
+
const result = await loader.discover(rootDir);
|
|
441
|
+
return result.found;
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Get built-in patterns for a provider
|
|
445
|
+
*/
|
|
446
|
+
export function getProviderPatterns(provider) {
|
|
447
|
+
const found = PROVIDER_PATTERNS.find((p) => p.provider.toLowerCase() === provider.toLowerCase());
|
|
448
|
+
return found ? [...found.patterns] : [];
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Get all supported provider names
|
|
452
|
+
*/
|
|
453
|
+
export function getSupportedProviders() {
|
|
454
|
+
return PROVIDER_PATTERNS.map((p) => p.provider);
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* Get generic patterns
|
|
458
|
+
*/
|
|
459
|
+
export function getGenericPatterns() {
|
|
460
|
+
return [...GENERIC_PATTERNS];
|
|
461
|
+
}
|
|
462
|
+
// Export built-in patterns for reference
|
|
463
|
+
export { PROVIDER_PATTERNS, GENERIC_PATTERNS };
|