rtexit-method 0.1.1 → 0.1.3
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/package.json +7 -2
- package/tools/installer/commands/install.js +8 -2
- package/tools/installer/lib/asset-manifest.js +20 -11
- package/tools/installer/lib/banner.js +14 -6
- package/tools/installer/lib/copy-assets.js +2 -2
- package/tools/installer/lib/prompts.js +9 -7
- package/tools/installer/lib/write-config.js +8 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rtexit-method",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "RTExit - AI-assisted Red Team methodology installer",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Exit Code",
|
|
@@ -46,5 +46,10 @@
|
|
|
46
46
|
],
|
|
47
47
|
"publishConfig": {
|
|
48
48
|
"access": "public"
|
|
49
|
-
}
|
|
49
|
+
},
|
|
50
|
+
"directories": {
|
|
51
|
+
"doc": "docs",
|
|
52
|
+
"test": "test"
|
|
53
|
+
},
|
|
54
|
+
"type": "commonjs"
|
|
50
55
|
}
|
|
@@ -20,17 +20,23 @@ async function installCommand(options = {}) {
|
|
|
20
20
|
|
|
21
21
|
const targetRoot = resolveTargetRoot(answers.targetDirectory);
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
const ides = answers.ides && answers.ides.length ? answers.ides : ['agents'];
|
|
24
|
+
await copyPackagedAssets({ repoRoot, targetRoot, ides });
|
|
24
25
|
await writeUserConfig({
|
|
25
26
|
targetRoot,
|
|
26
27
|
answers: {
|
|
27
28
|
language: answers.language,
|
|
28
29
|
document_output_language: answers.document_output_language,
|
|
29
|
-
skill_level: answers.skill_level,
|
|
30
30
|
},
|
|
31
31
|
});
|
|
32
32
|
|
|
33
|
+
const ideFolders = ides.map((ide) => {
|
|
34
|
+
const map = { agents: '.agents/skills', claude: '.claude/skills', trae: '.trae/skills', codex: '.codex/skills' };
|
|
35
|
+
return map[ide] || `.${ide}/skills`;
|
|
36
|
+
});
|
|
37
|
+
|
|
33
38
|
io.log('RTExit installed successfully.');
|
|
39
|
+
io.log(`Skills installed into: ${ideFolders.join(', ')}`);
|
|
34
40
|
io.log('Next steps:');
|
|
35
41
|
io.log('1. Open _rtexit/config.user.toml and complete client/project details');
|
|
36
42
|
io.log('2. Open your AI IDE in this project');
|
|
@@ -1,15 +1,24 @@
|
|
|
1
|
-
|
|
1
|
+
const IDE_SKILL_FOLDERS = {
|
|
2
|
+
agents: '.agents/skills',
|
|
3
|
+
claude: '.claude/skills',
|
|
4
|
+
trae: '.trae/skills',
|
|
5
|
+
codex: '.codex/skills',
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
function getInstallEntries(ides = ['agents']) {
|
|
9
|
+
const skillEntries = ides.map((ide) => ({
|
|
10
|
+
type: 'glob-dir-prefix',
|
|
11
|
+
base: 'packaged-assets/.agents/skills',
|
|
12
|
+
targetBase: IDE_SKILL_FOLDERS[ide] || `.${ide}/skills`,
|
|
13
|
+
prefix: 'rt-',
|
|
14
|
+
}));
|
|
15
|
+
|
|
2
16
|
return [
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
},
|
|
9
|
-
{ type: 'path', value: 'packaged-assets/_rtexit', target: '_rtexit' },
|
|
10
|
-
{ type: 'path', value: 'packaged-assets/templates', target: 'templates' },
|
|
11
|
-
{ type: 'path', value: 'packaged-assets/resources', target: 'resources' },
|
|
12
|
-
{ type: 'path', value: 'packaged-assets/RTEXIT.md', target: 'RTEXIT.md' }
|
|
17
|
+
...skillEntries,
|
|
18
|
+
{ type: 'path', value: 'packaged-assets/_rtexit', target: '_rtexit' },
|
|
19
|
+
{ type: 'path', value: 'packaged-assets/templates', target: 'templates' },
|
|
20
|
+
{ type: 'path', value: 'packaged-assets/resources', target: 'resources' },
|
|
21
|
+
{ type: 'path', value: 'packaged-assets/RTEXIT.md', target: 'RTEXIT.md' },
|
|
13
22
|
];
|
|
14
23
|
}
|
|
15
24
|
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
function renderBanner() {
|
|
2
|
+
const red = '\x1b[31m';
|
|
3
|
+
const dim = '\x1b[90m';
|
|
4
|
+
const reset = '\x1b[0m';
|
|
5
|
+
|
|
2
6
|
return [
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
`${red}██████╗ ████████╗███████╗██╗ ██╗██╗████████╗${reset}`,
|
|
8
|
+
`${red}██╔══██╗╚══██╔══╝██╔════╝╚██╗██╔╝██║╚══██╔══╝${reset}`,
|
|
9
|
+
`${red}██████╔╝ ██║ █████╗ ╚███╔╝ ██║ ██║${reset}`,
|
|
10
|
+
`${red}██╔══██╗ ██║ ██╔══╝ ██╔██╗ ██║ ██║${reset}`,
|
|
11
|
+
`${red}██║ ██║ ██║ ███████╗██╔╝ ██╗██║ ██║${reset}`,
|
|
12
|
+
`${red}╚═╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝${reset}`,
|
|
13
|
+
'',
|
|
14
|
+
`${dim}RTExit | AI-Assisted Red Team Methodology${reset}`,
|
|
15
|
+
`${dim}Install official RTExit framework assets into your project.${reset}`,
|
|
16
|
+
`${dim}Website: https://www.exitcode.me/${reset}`,
|
|
9
17
|
].join('\n');
|
|
10
18
|
}
|
|
11
19
|
|
|
@@ -17,8 +17,8 @@ function copyRecursive(source, target) {
|
|
|
17
17
|
fs.copyFileSync(source, target);
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
async function copyPackagedAssets({ repoRoot, targetRoot }) {
|
|
21
|
-
for (const entry of getInstallEntries()) {
|
|
20
|
+
async function copyPackagedAssets({ repoRoot, targetRoot, ides }) {
|
|
21
|
+
for (const entry of getInstallEntries(ides)) {
|
|
22
22
|
if (entry.type === 'path') {
|
|
23
23
|
const sourcePath = path.join(repoRoot, entry.value);
|
|
24
24
|
const targetPath = path.join(targetRoot, entry.target || entry.value);
|
|
@@ -22,14 +22,16 @@ async function askInstallQuestions({ cwd }) {
|
|
|
22
22
|
],
|
|
23
23
|
});
|
|
24
24
|
|
|
25
|
-
const
|
|
26
|
-
message: '
|
|
25
|
+
const ides = await prompts.multiselect({
|
|
26
|
+
message: 'Which AI IDEs are you using? (space to select, enter to confirm)',
|
|
27
27
|
options: [
|
|
28
|
-
{ value: '
|
|
29
|
-
{ value: '
|
|
30
|
-
{ value: '
|
|
31
|
-
{ value: '
|
|
28
|
+
{ value: 'agents', label: 'Cursor / Windsurf / VS Code (.agents/skills/)' },
|
|
29
|
+
{ value: 'claude', label: 'Claude Code (.claude/skills/)' },
|
|
30
|
+
{ value: 'trae', label: 'Trae (.trae/skills/)' },
|
|
31
|
+
{ value: 'codex', label: 'Codex / OpenAI (.codex/skills/)' },
|
|
32
32
|
],
|
|
33
|
+
initialValues: ['agents'],
|
|
34
|
+
required: true,
|
|
33
35
|
});
|
|
34
36
|
|
|
35
37
|
const confirmed = await prompts.confirm({
|
|
@@ -37,7 +39,7 @@ async function askInstallQuestions({ cwd }) {
|
|
|
37
39
|
initialValue: true,
|
|
38
40
|
});
|
|
39
41
|
|
|
40
|
-
return { targetDirectory, language, document_output_language,
|
|
42
|
+
return { targetDirectory, language, document_output_language, ides, confirmed };
|
|
41
43
|
}
|
|
42
44
|
|
|
43
45
|
module.exports = { askInstallQuestions };
|
|
@@ -17,14 +17,20 @@ async function writeUserConfig({ targetRoot, answers }) {
|
|
|
17
17
|
fs.mkdirSync(configDir, { recursive: true });
|
|
18
18
|
|
|
19
19
|
if (!fs.existsSync(configPath)) {
|
|
20
|
-
fs.writeFileSync(
|
|
20
|
+
fs.writeFileSync(
|
|
21
|
+
configPath,
|
|
22
|
+
`${buildConfigTemplate({
|
|
23
|
+
language: answers.language,
|
|
24
|
+
document_output_language: answers.document_output_language,
|
|
25
|
+
skill_level: '',
|
|
26
|
+
})}\n`,
|
|
27
|
+
);
|
|
21
28
|
return configPath;
|
|
22
29
|
}
|
|
23
30
|
|
|
24
31
|
let content = fs.readFileSync(configPath, 'utf8');
|
|
25
32
|
content = upsertKey(content, 'language', answers.language);
|
|
26
33
|
content = upsertKey(content, 'document_output_language', answers.document_output_language);
|
|
27
|
-
content = upsertKey(content, 'skill_level', answers.skill_level);
|
|
28
34
|
fs.writeFileSync(configPath, content);
|
|
29
35
|
return configPath;
|
|
30
36
|
}
|