Skip to content

Commit 6512709

Browse files
authored
Merge pull request #9 from TrueNine/dev
support glob pattern rules
2 parents 470e816 + fdceafd commit 6512709

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1794
-637
lines changed

cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@truenine/memory-sync-cli",
33
"type": "module",
4-
"version": "2026.10214.1083059",
4+
"version": "2026.10217.12221",
55
"description": "TrueNine Memory Synchronization CLI",
66
"author": "TrueNine",
77
"license": "AGPL-3.0-only",

cli/src/PluginPipeline.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,11 @@ export class PluginPipeline {
647647
? [...base.skills ?? [], ...addition.skills]
648648
: base.skills
649649

650+
const rules: CollectedInputContext['rules'] | undefined
651+
= addition.rules != null
652+
? [...base.rules ?? [], ...addition.rules]
653+
: base.rules
654+
650655
const aiAgentIgnoreConfigFiles: CollectedInputContext['aiAgentIgnoreConfigFiles'] | undefined
651656
= addition.aiAgentIgnoreConfigFiles != null
652657
? [...base.aiAgentIgnoreConfigFiles ?? [], ...addition.aiAgentIgnoreConfigFiles]
@@ -675,6 +680,7 @@ export class PluginPipeline {
675680
...fastCommands != null ? {fastCommands} : {},
676681
...subAgents != null ? {subAgents} : {},
677682
...skills != null ? {skills} : {},
683+
...rules != null ? {rules} : {},
678684
...aiAgentIgnoreConfigFiles != null ? {aiAgentIgnoreConfigFiles} : {},
679685
...globalMemory != null ? {globalMemory} : {},
680686
...shadowSourceProjectDir != null ? {shadowSourceProjectDir} : {},

cli/src/config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ function userConfigToPluginOptions(userConfig: UserConfigFile): Partial<PluginOp
3939
...userConfig.shadowSkillSourceDir != null ? {shadowSkillSourceDir: userConfig.shadowSkillSourceDir} : {},
4040
...userConfig.shadowFastCommandDir != null ? {shadowFastCommandDir: userConfig.shadowFastCommandDir} : {},
4141
...userConfig.shadowSubAgentDir != null ? {shadowSubAgentDir: userConfig.shadowSubAgentDir} : {},
42+
...userConfig.shadowRulesDir != null ? {shadowRulesDir: userConfig.shadowRulesDir} : {},
4243
...userConfig.globalMemoryFile != null ? {globalMemoryFile: userConfig.globalMemoryFile} : {},
4344
...userConfig.shadowProjectsDir != null ? {shadowProjectsDir: userConfig.shadowProjectsDir} : {},
4445
...userConfig.externalProjects != null ? {externalProjects: userConfig.externalProjects} : {},
@@ -232,6 +233,7 @@ export async function defineConfig(options: PluginOptions | DefineConfigOptions
232233
...merged.fastCommands != null && {fastCommands: merged.fastCommands},
233234
...merged.subAgents != null && {subAgents: merged.subAgents},
234235
...merged.skills != null && {skills: merged.skills},
236+
...merged.rules != null && {rules: merged.rules},
235237
...merged.globalMemory != null && {globalMemory: merged.globalMemory},
236238
...merged.aiAgentIgnoreConfigFiles != null && {aiAgentIgnoreConfigFiles: merged.aiAgentIgnoreConfigFiles},
237239
...merged.shadowSourceProjectDir != null && {shadowSourceProjectDir: merged.shadowSourceProjectDir},

cli/src/plugin.config.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import {defineConfig} from '@/config'
22
import {AgentsOutputPlugin} from '@/plugins/AgentsOutputPlugin'
33
import {AIAgentIgnoreConfigFileInputPlugin} from '@/plugins/AIAgentIgnoreConfigFileInputPlugin'
4-
import {AIAgentIgnoreConfigFileOutputPlugin} from '@/plugins/AIAgentIgnoreConfigFileOutputPlugin'
54
import {AntigravityOutputPlugin} from '@/plugins/AntigravityOutputPlugin'
65
import {ClaudeCodeCLIOutputPlugin} from '@/plugins/ClaudeCodeCLIOutputPlugin'
76
import {CodexCLIOutputPlugin} from '@/plugins/CodexCLIOutputPlugin'
@@ -25,10 +24,12 @@ import {ProjectPromptInputPlugin} from '@/plugins/ProjectPromptInputPlugin'
2524
import {QoderIDEPluginOutputPlugin} from '@/plugins/QoderIDEPluginOutputPlugin'
2625
import {ReadmeMdConfigFileOutputPlugin} from '@/plugins/ReadmeMdConfigFileOutputPlugin'
2726
import {ReadmeMdInputPlugin} from '@/plugins/ReadmeMdInputPlugin'
27+
import {RuleInputPlugin} from '@/plugins/RuleInputPlugin'
2828
import {ShadowProjectInputPlugin} from '@/plugins/ShadowProjectInputPlugin'
2929
import {SkillInputPlugin} from '@/plugins/SkillInputPlugin'
3030
import {SkillNonSrcFileSyncEffectInputPlugin} from '@/plugins/SkillNonSrcFileSyncEffectInputPlugin'
3131
import {SubAgentInputPlugin} from '@/plugins/SubAgentInputPlugin'
32+
import {TraeIDEOutputPlugin} from '@/plugins/TraeIDEOutputPlugin'
3233
import {VisualStudioCodeIDEConfigOutputPlugin} from '@/plugins/VisualStudioCodeIDEConfigOutputPlugin'
3334
import {WarpIDEOutputPlugin} from '@/plugins/WarpIDEOutputPlugin'
3435
import {WindsurfOutputPlugin} from '@/plugins/WindsurfOutputPlugin'
@@ -37,7 +38,6 @@ import {WorkspaceInputPlugin} from '@/plugins/WorkspaceInputPlugin'
3738
export default defineConfig({
3839
plugins: [
3940
new AgentsOutputPlugin(),
40-
new AIAgentIgnoreConfigFileOutputPlugin(),
4141
new AntigravityOutputPlugin(),
4242
new ClaudeCodeCLIOutputPlugin(),
4343
new CodexCLIOutputPlugin(),
@@ -48,6 +48,7 @@ export default defineConfig({
4848
new KiroCLIOutputPlugin(),
4949
new OpencodeCLIOutputPlugin(),
5050
new QoderIDEPluginOutputPlugin(),
51+
new TraeIDEOutputPlugin(),
5152
new WarpIDEOutputPlugin(),
5253
new WindsurfOutputPlugin(),
5354
new CursorOutputPlugin(),
@@ -68,6 +69,7 @@ export default defineConfig({
6869
new SkillInputPlugin(),
6970
new FastCommandInputPlugin(),
7071
new SubAgentInputPlugin(),
72+
new RuleInputPlugin(),
7173
new GlobalMemoryInputPlugin(),
7274
new ProjectPromptInputPlugin(),
7375
new ReadmeMdInputPlugin(),

cli/src/plugins/AIAgentIgnoreConfigFileInputPlugin.test.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ describe('aIAgentIgnoreConfigFileInputPlugin', () => {
5656

5757
vi.mocked(fs.existsSync).mockImplementation((filePath: any) => {
5858
const fileName = path.basename(String(filePath))
59-
return ['.qoderignore', '.cursorignore', '.warpindexignore', '.aiignore', '.codeignore'].includes(fileName)
59+
return ['.qoderignore', '.cursorignore', '.warpindexignore', '.aiignore', '.codeignore', '.traeignore'].includes(fileName)
6060
})
6161

6262
vi.mocked(fs.statSync).mockReturnValue({
@@ -71,13 +71,14 @@ describe('aIAgentIgnoreConfigFileInputPlugin', () => {
7171
if (fileName === '.warpindexignore') return 'warp ignore content'
7272
if (fileName === '.aiignore') return 'ai ignore content'
7373
if (fileName === '.codeignore') return 'windsurf code ignore content'
74+
if (fileName === '.traeignore') return 'trae ignore content'
7475
return ''
7576
})
7677

7778
const result = plugin.collect(ctx)
7879

7980
expect(result.aiAgentIgnoreConfigFiles).toBeDefined()
80-
expect(result.aiAgentIgnoreConfigFiles).toHaveLength(5)
81+
expect(result.aiAgentIgnoreConfigFiles).toHaveLength(6)
8182
expect(result.aiAgentIgnoreConfigFiles).toContainEqual({
8283
fileName: '.qoderignore',
8384
content: 'qoder ignore content'
@@ -98,6 +99,10 @@ describe('aIAgentIgnoreConfigFileInputPlugin', () => {
9899
fileName: '.codeignore',
99100
content: 'windsurf code ignore content'
100101
})
102+
expect(result.aiAgentIgnoreConfigFiles).toContainEqual({
103+
fileName: '.traeignore',
104+
content: 'trae ignore content'
105+
})
101106
})
102107

103108
it('should read only existing ignore files', () => {
@@ -151,13 +156,14 @@ describe('aIAgentIgnoreConfigFileInputPlugin', () => {
151156

152157
const result = plugin.collect(ctx)
153158

154-
expect(result.aiAgentIgnoreConfigFiles).toHaveLength(5)
159+
expect(result.aiAgentIgnoreConfigFiles).toHaveLength(6)
155160
expect(result.aiAgentIgnoreConfigFiles?.map(f => f.fileName)).toEqual([
156161
'.cursorignore',
157162
'.kiroignore',
158163
'.warpindexignore',
159164
'.aiignore',
160-
'.codeignore'
165+
'.codeignore',
166+
'.traeignore'
161167
])
162168
})
163169

@@ -179,13 +185,14 @@ describe('aIAgentIgnoreConfigFileInputPlugin', () => {
179185

180186
const result = plugin.collect(ctx)
181187

182-
expect(result.aiAgentIgnoreConfigFiles).toHaveLength(5)
188+
expect(result.aiAgentIgnoreConfigFiles).toHaveLength(6)
183189
expect(result.aiAgentIgnoreConfigFiles?.map(f => f.fileName)).toEqual([
184190
'.qoderignore',
185191
'.kiroignore',
186192
'.warpindexignore',
187193
'.aiignore',
188-
'.codeignore'
194+
'.codeignore',
195+
'.traeignore'
189196
])
190197
expect(ctx.logger.warn).toHaveBeenCalled()
191198
})
@@ -204,7 +211,7 @@ describe('aIAgentIgnoreConfigFileInputPlugin', () => {
204211

205212
plugin.collect(ctx)
206213

207-
expect(ctx.logger.debug).toHaveBeenCalledTimes(6)
214+
expect(ctx.logger.debug).toHaveBeenCalledTimes(7)
208215
})
209216

210217
it('should support custom shadowSourceProjectDir', () => {

cli/src/plugins/AIAgentIgnoreConfigFileInputPlugin.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {AbstractInputPlugin} from './AbstractInputPlugin'
99
/**
1010
* Ignore file names to read from shadow project dist directory
1111
*/
12-
const IGNORE_FILE_NAMES = ['.qoderignore', '.cursorignore', '.kiroignore', '.warpindexignore', '.aiignore', '.codeignore'] as const
12+
const IGNORE_FILE_NAMES = ['.qoderignore', '.cursorignore', '.kiroignore', '.warpindexignore', '.aiignore', '.codeignore', '.traeignore'] as const
1313

1414
export class AIAgentIgnoreConfigFileInputPlugin extends AbstractInputPlugin {
1515
constructor() {

0 commit comments

Comments
 (0)