@ryuenn3123/agentic-senior-core 6.5.2 → 6.6.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.
- package/.agents/plugins/agentic-senior-core/.codex-plugin/plugin.json +1 -1
- package/.agents/plugins/agentic-senior-core/hooks/dedup-gate.js +42 -2
- package/.agents/plugins/agentic-senior-core/kilo-plugin/agentic-senior-core.js +42 -0
- package/.agents/plugins/agentic-senior-core/plugin.json +1 -1
- package/.asc/dedup-config.json +1 -0
- package/gemini-extension.json +1 -1
- package/lib/cli/commands/adapter.mjs +21 -2
- package/lib/cli/commands/git-hook-generator.mjs +55 -10
- package/lib/cli/commands/global.mjs +51 -4
- package/lib/cli/commands/status.mjs +7 -2
- package/lib/cli/commands/uninstall.mjs +3 -1
- package/package.json +1 -1
- package/plugin.yaml +1 -1
|
@@ -116,6 +116,8 @@ process.stdin.on('data', chunk => {
|
|
|
116
116
|
const config = loadDedupConfig();
|
|
117
117
|
if (!isQualifyingEdit(toolName, toolInput, config)) { process.exit(0); return; }
|
|
118
118
|
|
|
119
|
+
if (hasValidInlineIgnore(filePath)) { process.exit(0); return; }
|
|
120
|
+
|
|
119
121
|
const scanDir = resolveScanDir(filePath, config);
|
|
120
122
|
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'asc-dedup-'));
|
|
121
123
|
|
|
@@ -127,7 +129,7 @@ process.stdin.on('data', chunk => {
|
|
|
127
129
|
const report = runJscpdScan(scanCmd, tmpDir);
|
|
128
130
|
if (!report) { cleanup(tmpDir); process.exit(0); return; }
|
|
129
131
|
|
|
130
|
-
const finding = checkForDuplicates(report, filePath);
|
|
132
|
+
const finding = checkForDuplicates(report, filePath, config);
|
|
131
133
|
if (!finding) { cleanup(tmpDir); process.exit(0); return; }
|
|
132
134
|
|
|
133
135
|
const nudge = '[ASC Dedup] ' + path.basename(filePath) + ' looks similar to '
|
|
@@ -298,10 +300,44 @@ function loadReport(tmpDir) {
|
|
|
298
300
|
}
|
|
299
301
|
}
|
|
300
302
|
|
|
301
|
-
function
|
|
303
|
+
function hasValidInlineIgnore(filePath) {
|
|
304
|
+
try {
|
|
305
|
+
if (!fs.existsSync(filePath)) return false;
|
|
306
|
+
var content = fs.readFileSync(filePath, 'utf8');
|
|
307
|
+
if (content.indexOf('jscpd:ignore-start') !== -1) return true;
|
|
308
|
+
var match = content.match(/asc-dedup:ignore\s*--\s*(.+)/i);
|
|
309
|
+
return Boolean(match && match[1] && match[1].trim().length > 0);
|
|
310
|
+
} catch (_) {
|
|
311
|
+
return false;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
function isAllowedDuplicate(fileA, fileB, allowedDuplicates) {
|
|
316
|
+
if (!Array.isArray(allowedDuplicates) || allowedDuplicates.length === 0) return false;
|
|
317
|
+
var normA = path.resolve(fileA).replace(/\\/g, '/').toLowerCase();
|
|
318
|
+
var normB = path.resolve(fileB).replace(/\\/g, '/').toLowerCase();
|
|
319
|
+
var baseA = path.basename(fileA).toLowerCase();
|
|
320
|
+
var baseB = path.basename(fileB).toLowerCase();
|
|
321
|
+
|
|
322
|
+
for (var i = 0; i < allowedDuplicates.length; i++) {
|
|
323
|
+
var pair = allowedDuplicates[i];
|
|
324
|
+
if (!Array.isArray(pair) || pair.length < 2) continue;
|
|
325
|
+
var p0Norm = path.resolve(pair[0]).replace(/\\/g, '/').toLowerCase();
|
|
326
|
+
var p1Norm = path.resolve(pair[1]).replace(/\\/g, '/').toLowerCase();
|
|
327
|
+
var p0Base = path.basename(pair[0]).toLowerCase();
|
|
328
|
+
var p1Base = path.basename(pair[1]).toLowerCase();
|
|
329
|
+
|
|
330
|
+
if ((normA === p0Norm && normB === p1Norm) || (normA === p1Norm && normB === p0Norm)) return true;
|
|
331
|
+
if ((baseA === p0Base && baseB === p1Base) || (baseA === p1Base && baseB === p0Base)) return true;
|
|
332
|
+
}
|
|
333
|
+
return false;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
function checkForDuplicates(report, filePath, config) {
|
|
302
337
|
var duplicates = report.duplicates || [];
|
|
303
338
|
if (duplicates.length === 0) return null;
|
|
304
339
|
|
|
340
|
+
var allowedDuplicates = config && config.allowedDuplicates;
|
|
305
341
|
var normalizedTarget = path.resolve(filePath).replace(/\\/g, '/').toLowerCase();
|
|
306
342
|
var targetBasename = path.basename(filePath);
|
|
307
343
|
|
|
@@ -314,6 +350,10 @@ function checkForDuplicates(report, filePath) {
|
|
|
314
350
|
var otherRaw = firstName === normalizedTarget ? dup.secondFile.name : dup.firstFile.name;
|
|
315
351
|
var otherBasename = path.basename(otherRaw);
|
|
316
352
|
|
|
353
|
+
if (isAllowedDuplicate(filePath, otherRaw, allowedDuplicates)) {
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
|
|
317
357
|
// Skip framework-conventional filenames in different directories — identical names
|
|
318
358
|
// are mandated by the framework (e.g. Next.js page.tsx, Angular *.component.ts),
|
|
319
359
|
// not copy-paste duplication.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// Native Kilo / OpenCode Plugin for Agentic Senior Core
|
|
2
|
+
// Hooks into system prompt transform, session compaction, and shell environment.
|
|
3
|
+
|
|
4
|
+
const ASC_GUARDRAILS = `
|
|
5
|
+
# Agentic Senior Core Rules
|
|
6
|
+
- Write code like a staff engineer. Efficient, safe, maintainable.
|
|
7
|
+
- Before writing code: 1) Need built? 2) Codebase reuse? 3) Stdlib? 4) Dependency? 5) One function? 6) Minimum code.
|
|
8
|
+
- Parameterize all queries. Validate inputs at trust boundaries. Never commit secrets.
|
|
9
|
+
- Early returns over deep nesting. Delete code that carries no value.
|
|
10
|
+
`;
|
|
11
|
+
|
|
12
|
+
const server = async ({ project, directory, worktree }) => {
|
|
13
|
+
return {
|
|
14
|
+
"experimental.chat.system.transform": async (input, output) => {
|
|
15
|
+
if (Array.isArray(output.system)) {
|
|
16
|
+
const hasASC = output.system.some(item => typeof item === 'string' && item.includes('Agentic Senior Core'));
|
|
17
|
+
if (!hasASC) {
|
|
18
|
+
output.system.push(ASC_GUARDRAILS.trim());
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"experimental.session.compacting": async (input, output) => {
|
|
23
|
+
if (Array.isArray(output.context)) {
|
|
24
|
+
output.context.push(
|
|
25
|
+
"## Agentic Senior Core (Persisted Context)\n" +
|
|
26
|
+
"- Maintain strict security guardrails and non-breaking API contracts.\n" +
|
|
27
|
+
"- Prefer clean minimal logic over premature abstractions."
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"shell.env": async (input, output) => {
|
|
32
|
+
if (output.env) {
|
|
33
|
+
output.env.ASC_ENABLED = "1";
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export default {
|
|
40
|
+
id: "agentic-senior-core",
|
|
41
|
+
server,
|
|
42
|
+
};
|
package/.asc/dedup-config.json
CHANGED
package/gemini-extension.json
CHANGED
|
@@ -60,8 +60,11 @@ const ADAPTER_TARGETS = {
|
|
|
60
60
|
},
|
|
61
61
|
kilocode: {
|
|
62
62
|
label: 'Kilo Code',
|
|
63
|
-
targetPath: '.
|
|
63
|
+
targetPath: '.kilo/rules/agentic-senior-core.md',
|
|
64
|
+
legacyTargetPath: '.kilocode/rules/agentic-senior-core.md',
|
|
65
|
+
pluginTargetPath: '.kilo/plugin/agentic-senior-core.js',
|
|
64
66
|
sourcePath: '.agents/plugins/agentic-senior-core/rules/agentic-senior-core.md',
|
|
67
|
+
pluginSourcePath: '.agents/plugins/agentic-senior-core/kilo-plugin/agentic-senior-core.js',
|
|
65
68
|
},
|
|
66
69
|
roo: {
|
|
67
70
|
label: 'Roo Code',
|
|
@@ -117,7 +120,23 @@ async function generateAdapter(targetDirectory, adapterKey) {
|
|
|
117
120
|
}
|
|
118
121
|
|
|
119
122
|
await fs.writeFile(targetPath, finalContent, 'utf8');
|
|
120
|
-
|
|
123
|
+
|
|
124
|
+
if (adapterKey === 'kilocode') {
|
|
125
|
+
if (adapter.pluginSourcePath && adapter.pluginTargetPath) {
|
|
126
|
+
const pluginSource = path.join(REPOSITORY_ROOT, adapter.pluginSourcePath);
|
|
127
|
+
const pluginTarget = path.join(targetDirectory, adapter.pluginTargetPath);
|
|
128
|
+
if (await pathExists(pluginSource)) {
|
|
129
|
+
await fs.mkdir(path.dirname(pluginTarget), { recursive: true });
|
|
130
|
+
await fs.copyFile(pluginSource, pluginTarget);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (adapter.legacyTargetPath) {
|
|
134
|
+
const legacyTarget = path.join(targetDirectory, adapter.legacyTargetPath);
|
|
135
|
+
await fs.mkdir(path.dirname(legacyTarget), { recursive: true });
|
|
136
|
+
await fs.writeFile(legacyTarget, finalContent, 'utf8');
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
121
140
|
console.log(` ${adapter.label}: ${adapter.targetPath} ... OK`);
|
|
122
141
|
return true;
|
|
123
142
|
}
|
|
@@ -68,9 +68,42 @@ function isFrameworkConventional(basename) {
|
|
|
68
68
|
return false;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
// Minimum thresholds
|
|
72
|
-
const
|
|
73
|
-
const
|
|
71
|
+
// Minimum blocking thresholds for Git pre-commit gate
|
|
72
|
+
const MIN_BLOCKING_LINES = 15;
|
|
73
|
+
const MIN_BLOCKING_PERCENT = 25;
|
|
74
|
+
|
|
75
|
+
function hasValidInlineIgnore(filePath) {
|
|
76
|
+
try {
|
|
77
|
+
if (!fs.existsSync(filePath)) return false;
|
|
78
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
79
|
+
if (content.includes('jscpd:ignore-start')) return true;
|
|
80
|
+
const match = content.match(/asc-dedup:ignore\\s*--\\s*(.+)/i);
|
|
81
|
+
return Boolean(match && match[1] && match[1].trim().length > 0);
|
|
82
|
+
} catch (_) {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function isAllowedDuplicate(fileA, fileB, allowedDuplicates) {
|
|
88
|
+
if (!Array.isArray(allowedDuplicates) || allowedDuplicates.length === 0) return false;
|
|
89
|
+
const normA = path.resolve(fileA).replace(/\\\\/g, '/').toLowerCase();
|
|
90
|
+
const normB = path.resolve(fileB).replace(/\\\\/g, '/').toLowerCase();
|
|
91
|
+
const baseA = path.basename(fileA).toLowerCase();
|
|
92
|
+
const baseB = path.basename(fileB).toLowerCase();
|
|
93
|
+
|
|
94
|
+
for (let i = 0; i < allowedDuplicates.length; i++) {
|
|
95
|
+
const pair = allowedDuplicates[i];
|
|
96
|
+
if (!Array.isArray(pair) || pair.length < 2) continue;
|
|
97
|
+
const p0Norm = path.resolve(pair[0]).replace(/\\\\/g, '/').toLowerCase();
|
|
98
|
+
const p1Norm = path.resolve(pair[1]).replace(/\\\\/g, '/').toLowerCase();
|
|
99
|
+
const p0Base = path.basename(pair[0]).toLowerCase();
|
|
100
|
+
const p1Base = path.basename(pair[1]).toLowerCase();
|
|
101
|
+
|
|
102
|
+
if ((normA === p0Norm && normB === p1Norm) || (normA === p1Norm && normB === p0Norm)) return true;
|
|
103
|
+
if ((baseA === p0Base && baseB === p1Base) || (baseA === p1Base && baseB === p0Base)) return true;
|
|
104
|
+
}
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
74
107
|
|
|
75
108
|
function getStagedFiles(cwd) {
|
|
76
109
|
try {
|
|
@@ -158,10 +191,11 @@ function loadReport(tmpDir) {
|
|
|
158
191
|
}
|
|
159
192
|
}
|
|
160
193
|
|
|
161
|
-
function checkForDuplicates(report, stagedSourceFiles, cwd) {
|
|
194
|
+
function checkForDuplicates(report, stagedSourceFiles, cwd, config) {
|
|
162
195
|
const duplicates = report.duplicates || [];
|
|
163
196
|
if (duplicates.length === 0) return null;
|
|
164
197
|
|
|
198
|
+
const allowedDuplicates = config && config.allowedDuplicates;
|
|
165
199
|
const normalizedStagedMap = new Map();
|
|
166
200
|
for (const f of stagedSourceFiles) {
|
|
167
201
|
const norm = path.resolve(cwd, f).replace(/\\\\/g, '/').toLowerCase();
|
|
@@ -179,13 +213,24 @@ function checkForDuplicates(report, stagedSourceFiles, cwd) {
|
|
|
179
213
|
if (isFirstStaged || isSecondStaged) {
|
|
180
214
|
const stagedFile = isFirstStaged ? normalizedStagedMap.get(firstName) : normalizedStagedMap.get(secondName);
|
|
181
215
|
const otherRaw = isFirstStaged ? dup.secondFile.name : dup.firstFile.name;
|
|
216
|
+
const stagedPath = path.resolve(cwd, stagedFile);
|
|
217
|
+
const otherPath = path.resolve(cwd, otherRaw);
|
|
218
|
+
|
|
219
|
+
if (hasValidInlineIgnore(stagedPath) || hasValidInlineIgnore(otherPath)) {
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (isAllowedDuplicate(stagedPath, otherPath, allowedDuplicates)) {
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
|
|
182
227
|
const otherBasename = path.basename(otherRaw);
|
|
183
228
|
const stagedBasename = path.basename(stagedFile);
|
|
184
229
|
|
|
185
230
|
// Skip framework-conventional filenames in different directories
|
|
186
231
|
if (isFrameworkConventional(stagedBasename)
|
|
187
232
|
&& isFrameworkConventional(otherBasename)
|
|
188
|
-
&& path.dirname(
|
|
233
|
+
&& path.dirname(stagedPath) !== path.dirname(otherPath)) {
|
|
189
234
|
continue;
|
|
190
235
|
}
|
|
191
236
|
|
|
@@ -193,19 +238,19 @@ function checkForDuplicates(report, stagedSourceFiles, cwd) {
|
|
|
193
238
|
// Calculate percent relative to the actual staged file size
|
|
194
239
|
let totalFileLines = 1;
|
|
195
240
|
try {
|
|
196
|
-
totalFileLines = fs.readFileSync(
|
|
241
|
+
totalFileLines = fs.readFileSync(stagedPath, 'utf8').split('\\n').length || 1;
|
|
197
242
|
} catch (_) {
|
|
198
243
|
totalFileLines = dup.firstFile.lines || dup.secondFile.lines || lines || 1;
|
|
199
244
|
}
|
|
200
245
|
const percent = Math.round((lines / totalFileLines) * 100);
|
|
201
246
|
|
|
202
|
-
// Skip
|
|
203
|
-
if (lines <
|
|
247
|
+
// Skip matches below blocking threshold
|
|
248
|
+
if (lines < MIN_BLOCKING_LINES || percent < MIN_BLOCKING_PERCENT) {
|
|
204
249
|
continue;
|
|
205
250
|
}
|
|
206
251
|
|
|
207
252
|
// Show relative path for actionable messages
|
|
208
|
-
const matchedFile = path.relative(cwd,
|
|
253
|
+
const matchedFile = path.relative(cwd, otherPath).replace(/\\\\/g, '/');
|
|
209
254
|
return { stagedFile, matchedFile, lines, percent };
|
|
210
255
|
}
|
|
211
256
|
}
|
|
@@ -274,7 +319,7 @@ function runPreCommitGate() {
|
|
|
274
319
|
const scanCmd = \` "\${scanDir}" --min-tokens \${minTokens} --reporters json --silent --output "\${tmpDir}" \${ignoreFlags}\`;
|
|
275
320
|
const report = runJscpdScan(scanCmd, cwd, tmpDir);
|
|
276
321
|
if (report) {
|
|
277
|
-
finding = checkForDuplicates(report, currentStagedSource, cwd);
|
|
322
|
+
finding = checkForDuplicates(report, currentStagedSource, cwd, config);
|
|
278
323
|
if (finding) break;
|
|
279
324
|
}
|
|
280
325
|
}
|
|
@@ -56,10 +56,13 @@ const GLOBAL_TARGETS = {
|
|
|
56
56
|
},
|
|
57
57
|
kilocode: {
|
|
58
58
|
label: 'Kilo Code',
|
|
59
|
-
kind: '
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
kind: 'kilo-global',
|
|
60
|
+
rulesSourcePath: '.agents/plugins/agentic-senior-core/rules/agentic-senior-core.md',
|
|
61
|
+
pluginSourcePath: '.agents/plugins/agentic-senior-core/kilo-plugin/agentic-senior-core.js',
|
|
62
|
+
targetPath: () => path.join(HOME, '.config', 'kilo', 'rules', 'agentic-senior-core.md'),
|
|
63
|
+
legacyTargetPath: () => path.join(HOME, '.kilocode', 'rules', 'agentic-senior-core.md'),
|
|
64
|
+
pluginTargetPath: () => path.join(HOME, '.config', 'kilo', 'plugin', 'agentic-senior-core.js'),
|
|
65
|
+
note: 'Installs global plugin to ~/.config/kilo/plugin/ and rules to ~/.config/kilo/rules/.',
|
|
63
66
|
},
|
|
64
67
|
kiro: {
|
|
65
68
|
label: 'Kiro',
|
|
@@ -201,6 +204,46 @@ async function installCodexGlobal(target) {
|
|
|
201
204
|
return true;
|
|
202
205
|
}
|
|
203
206
|
|
|
207
|
+
async function installKiloGlobal(target) {
|
|
208
|
+
const rulesSource = path.join(REPOSITORY_ROOT, target.rulesSourcePath);
|
|
209
|
+
const pluginSource = path.join(REPOSITORY_ROOT, target.pluginSourcePath);
|
|
210
|
+
const rulesTarget = target.targetPath();
|
|
211
|
+
const pluginTarget = target.pluginTargetPath();
|
|
212
|
+
const legacyRulesTarget = target.legacyTargetPath();
|
|
213
|
+
|
|
214
|
+
if (!(await pathExists(rulesSource))) {
|
|
215
|
+
console.error(` ${target.label}: rules source not found ... FAIL`);
|
|
216
|
+
return false;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
await fs.mkdir(path.dirname(rulesTarget), { recursive: true });
|
|
220
|
+
await fs.copyFile(rulesSource, rulesTarget);
|
|
221
|
+
|
|
222
|
+
await fs.mkdir(path.dirname(legacyRulesTarget), { recursive: true });
|
|
223
|
+
await fs.copyFile(rulesSource, legacyRulesTarget);
|
|
224
|
+
|
|
225
|
+
if (await pathExists(pluginSource)) {
|
|
226
|
+
await fs.mkdir(path.dirname(pluginTarget), { recursive: true });
|
|
227
|
+
await fs.copyFile(pluginSource, pluginTarget);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (process.env.APPDATA) {
|
|
231
|
+
const appDataKiloPlugin = path.join(process.env.APPDATA, 'kilo', 'plugin', 'agentic-senior-core.js');
|
|
232
|
+
const appDataKiloRules = path.join(process.env.APPDATA, 'kilo', 'rules', 'agentic-senior-core.md');
|
|
233
|
+
try {
|
|
234
|
+
if (await pathExists(pluginSource)) {
|
|
235
|
+
await fs.mkdir(path.dirname(appDataKiloPlugin), { recursive: true });
|
|
236
|
+
await fs.copyFile(pluginSource, appDataKiloPlugin);
|
|
237
|
+
}
|
|
238
|
+
await fs.mkdir(path.dirname(appDataKiloRules), { recursive: true });
|
|
239
|
+
await fs.copyFile(rulesSource, appDataKiloRules);
|
|
240
|
+
} catch (_) {}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
console.log(` ${target.label}: ${rulesTarget} & ${pluginTarget} ... OK`);
|
|
244
|
+
return true;
|
|
245
|
+
}
|
|
246
|
+
|
|
204
247
|
async function installAntigravityIde(target) {
|
|
205
248
|
const pluginSource = path.join(REPOSITORY_ROOT, target.pluginSourcePath);
|
|
206
249
|
const rulesSource = path.join(REPOSITORY_ROOT, target.rulesSourcePath);
|
|
@@ -319,6 +362,10 @@ async function installGlobalTarget(targetKey) {
|
|
|
319
362
|
return await installCodexGlobal(target);
|
|
320
363
|
}
|
|
321
364
|
|
|
365
|
+
if (target.kind === 'kilo-global') {
|
|
366
|
+
return await installKiloGlobal(target);
|
|
367
|
+
}
|
|
368
|
+
|
|
322
369
|
const sourcePath = path.join(REPOSITORY_ROOT, target.sourcePath);
|
|
323
370
|
const targetPath = target.targetPath();
|
|
324
371
|
|
|
@@ -111,8 +111,13 @@ const IDE_CHECKS = [
|
|
|
111
111
|
{
|
|
112
112
|
name: 'Kilo Code',
|
|
113
113
|
type: 'adapter',
|
|
114
|
-
checkPaths: [
|
|
115
|
-
|
|
114
|
+
checkPaths: [
|
|
115
|
+
path.join(HOME, '.config', 'kilo'),
|
|
116
|
+
path.join(HOME, '.kilo'),
|
|
117
|
+
path.join(HOME, '.kilocode'),
|
|
118
|
+
...(process.env.APPDATA ? [path.join(process.env.APPDATA, 'kilo')] : []),
|
|
119
|
+
],
|
|
120
|
+
installHint: 'asc global --kilocode',
|
|
116
121
|
},
|
|
117
122
|
{
|
|
118
123
|
name: 'Roo Code',
|
|
@@ -14,7 +14,9 @@ const ADAPTER_FILES = [
|
|
|
14
14
|
{ label: 'Continue', path: '.continue/rules/agentic-senior-core.md' },
|
|
15
15
|
{ label: 'Zed', path: '.zed/rules/agentic-senior-core.md' },
|
|
16
16
|
{ label: 'Aider', path: 'CONVENTIONS.md' },
|
|
17
|
-
{ label: 'Kilo Code', path: '.
|
|
17
|
+
{ label: 'Kilo Code (modern rules)', path: '.kilo/rules/agentic-senior-core.md' },
|
|
18
|
+
{ label: 'Kilo Code (modern plugin)', path: '.kilo/plugin/agentic-senior-core.js' },
|
|
19
|
+
{ label: 'Kilo Code (legacy rules)', path: '.kilocode/rules/agentic-senior-core.md' },
|
|
18
20
|
{ label: 'Roo Code', path: '.roo/rules/agentic-senior-core.md' },
|
|
19
21
|
{ label: 'OpenHands', path: '.openhands/microagents/agentic-senior-core.md' },
|
|
20
22
|
{ label: 'ASC Compiled Validator', path: '.asc/hooks/pre-commit-validator.cjs' },
|
package/package.json
CHANGED
package/plugin.yaml
CHANGED