thachvd-kit 1.0.19 → 1.0.21
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/.agent/docs/architecture.md +3 -2
- package/.agent/docs/conventions.md +1 -1
- package/.agent/docs/tooling.md +26 -9
- package/.agent/skills/project-onboarding/SKILL.md +1 -1
- package/.agent/skills/using-git-worktrees/SKILL.md +2 -3
- package/.agent/skills/writing-skills/SKILL.md +170 -110
- package/.agent/workflows/review.md +125 -0
- package/.agent/workflows/spec.md +140 -0
- package/README.md +45 -44
- package/bin/cli.js +399 -320
- package/kit/README.md +2 -1
- package/package.json +1 -1
- package/skills/code-review-checklist/SKILL.md +142 -109
- package/skills/project-onboarding/SKILL.md +1 -1
- package/skills/tdd-workflow/SKILL.md +25 -1
- package/skills/using-git-worktrees/SKILL.md +2 -3
- package/skills/verification-before-completion/SKILL.md +24 -10
- package/skills/writing-skills/SKILL.md +170 -110
package/bin/cli.js
CHANGED
|
@@ -136,9 +136,10 @@ ${pc.bold('Options:')}
|
|
|
136
136
|
--help Show this help message
|
|
137
137
|
|
|
138
138
|
${pc.bold('What gets generated:')}
|
|
139
|
-
AGENTS.md Shared instructions for Codex, Antigravity,
|
|
139
|
+
AGENTS.md Shared instructions for Codex, Antigravity, Claude Code, and Cursor
|
|
140
140
|
CLAUDE.md Claude Code entry file that imports AGENTS.md
|
|
141
141
|
GEMINI.md Antigravity entry file that points to AGENTS.md
|
|
142
|
+
.cursorrules Cursor entry file that points to AGENTS.md
|
|
142
143
|
.agent/ Shared docs, skills, workflows, agents, and rules
|
|
143
144
|
~/.codex/skills/ Selected Codex skills copied to global user dir (shows in $ menu)
|
|
144
145
|
.claude/skills/ Selected Claude Code project skills copied from .agent/skills
|
|
@@ -885,33 +886,31 @@ function resolveAgentTable(data) {
|
|
|
885
886
|
rows.push(["Debug", "debugger", "systematic-debugging"]);
|
|
886
887
|
rows.push(["Security", "security-auditor", "vulnerability-scanner"]);
|
|
887
888
|
rows.push(["Planning", "project-planner", "brainstorming, plan-writing"]);
|
|
888
|
-
|
|
889
|
-
return rows;
|
|
890
|
-
}
|
|
891
|
-
|
|
892
|
-
// --- File Generators ---
|
|
893
|
-
|
|
894
|
-
function generateSharedAgentsMd(data) {
|
|
895
|
-
return `# AGENTS.md
|
|
896
|
-
|
|
897
|
-
Shared operating instructions for Codex, Antigravity, and Claude Code.
|
|
898
|
-
|
|
899
|
-
## Startup
|
|
900
|
-
|
|
901
|
-
1. Read this file first.
|
|
902
|
-
2. Read \`.agent/docs/project.md\` for detected stack, commands, and routing.
|
|
889
|
+
|
|
903
890
|
return rows;
|
|
891
|
+
}
|
|
892
|
+
// --- File Generators ---
|
|
893
|
+
|
|
894
|
+
function generateSharedAgentsMd(data) {
|
|
895
|
+
return `# AGENTS.md
|
|
896
|
+
|
|
897
|
+
Shared operating instructions for Codex, Antigravity, Claude Code, and Cursor.
|
|
898
|
+
|
|
899
|
+
## Startup
|
|
900
|
+
|
|
901
|
+
1. Read this file first.
|
|
902
|
+
2. Read \`.agent/docs/project.md\` for detected stack, commands, and routing.
|
|
904
903
|
3. Read \`.agent/docs/workflow.md\` for the task flow before editing.
|
|
905
904
|
4. Read \`.agent/docs/architecture.md\` and \`.agent/docs/conventions.md\` before planning code changes.
|
|
906
905
|
5. Read \`.agent/docs/tooling.md\` when the task needs Playwright, codegraph, MCP, or native Codex/Claude skill setup.
|
|
907
906
|
6. Select and load only the agent, skill, or workflow files that match the current task.
|
|
908
|
-
|
|
909
|
-
If any \`.agent/docs/*.md\` file still contains \`TODO: refine\`, update the docs by scanning the project before making product code changes.
|
|
910
|
-
|
|
911
|
-
## Task Flow
|
|
912
|
-
|
|
913
|
-
- Questions and analysis: answer directly, cite relevant files when useful, and do not edit code.
|
|
914
|
-
- Simple fix: inspect dependencies, make the smallest change, run focused verification.
|
|
915
|
-
- Feature or refactor: define success criteria, make a short plan, implement, then verify.
|
|
907
|
+
|
|
908
|
+
If any \`.agent/docs/*.md\` file still contains \`TODO: refine\`, update the docs by scanning the project before making product code changes.
|
|
909
|
+
|
|
910
|
+
## Task Flow
|
|
911
|
+
|
|
912
|
+
- Questions and analysis: answer directly, cite relevant files when useful, and do not edit code.
|
|
913
|
+
- Simple fix: inspect dependencies, make the smallest change, run focused verification.
|
|
914
|
+
- Feature or refactor: define success criteria, make a short plan, implement, then verify.
|
|
916
915
|
- Multi-domain work: use \`.agent/workflows/orchestrate.md\` and route to the relevant specialist docs.
|
|
917
916
|
- UI work: read \`.agent/agents/frontend-specialist.md\` and applicable design skills before editing.
|
|
918
917
|
|
|
@@ -927,16 +926,16 @@ If any \`.agent/docs/*.md\` file still contains \`TODO: refine\`, update the doc
|
|
|
927
926
|
- When creating or improving skills, use \`writing-skills\` first and make the \`description\` field specific enough for implicit invocation.
|
|
928
927
|
|
|
929
928
|
## Rules
|
|
930
|
-
|
|
931
|
-
- Respond in the user's language; keep code, identifiers, and code comments in English.
|
|
932
|
-
- State assumptions when the request is ambiguous.
|
|
933
|
-
- Prefer the existing project style over new abstractions.
|
|
934
|
-
- Keep changes surgical and remove only dead code introduced by your change.
|
|
935
|
-
- Tests or equivalent verification are mandatory before claiming done.
|
|
936
|
-
- Keep files under ${data.max_file_lines || '300'} lines unless the project already has a different standard in \`.agent/docs/conventions.md\`.
|
|
937
|
-
|
|
938
|
-
## Shared Knowledge
|
|
939
|
-
|
|
929
|
+
|
|
930
|
+
- Respond in the user's language; keep code, identifiers, and code comments in English.
|
|
931
|
+
- State assumptions when the request is ambiguous.
|
|
932
|
+
- Prefer the existing project style over new abstractions.
|
|
933
|
+
- Keep changes surgical and remove only dead code introduced by your change.
|
|
934
|
+
- Tests or equivalent verification are mandatory before claiming done.
|
|
935
|
+
- Keep files under ${data.max_file_lines || '300'} lines unless the project already has a different standard in \`.agent/docs/conventions.md\`.
|
|
936
|
+
|
|
937
|
+
## Shared Knowledge
|
|
938
|
+
|
|
940
939
|
- Project docs: \`.agent/docs/\`
|
|
941
940
|
- Specialist agents: \`.agent/agents/\`
|
|
942
941
|
- Skills: \`.agent/skills/\`
|
|
@@ -945,180 +944,190 @@ If any \`.agent/docs/*.md\` file still contains \`TODO: refine\`, update the doc
|
|
|
945
944
|
- Workflows: \`.agent/workflows/\`
|
|
946
945
|
- Tooling setup: \`.agent/docs/tooling.md\`
|
|
947
946
|
- Antigravity mirror rules: \`.agent/rules/GEMINI.md\`
|
|
947
|
+
- Cursor entry rules: \`.cursorrules\`
|
|
948
948
|
`;
|
|
949
949
|
}
|
|
950
|
-
|
|
951
|
-
function generateSharedClaudeMd() {
|
|
952
|
-
return `@AGENTS.md
|
|
953
|
-
|
|
954
|
-
## Claude Code
|
|
955
|
-
|
|
956
|
-
This repository uses AGENTS.md as the shared cross-agent entry file. Follow the imported instructions and keep Claude-specific notes here only when they cannot apply to Codex or Antigravity.
|
|
957
|
-
`;
|
|
958
|
-
}
|
|
959
|
-
|
|
960
|
-
function generateSharedGeminiMd() {
|
|
961
|
-
return `# GEMINI.md
|
|
962
|
-
|
|
963
|
-
Antigravity entry file for this project.
|
|
964
|
-
|
|
965
|
-
Read AGENTS.md first, then follow the shared docs under .agent/docs/.
|
|
966
|
-
`;
|
|
967
|
-
}
|
|
968
|
-
|
|
969
|
-
function
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
dev = '
|
|
1010
|
-
lint = '
|
|
1011
|
-
}
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
-
|
|
1044
|
-
-
|
|
1045
|
-
-
|
|
1046
|
-
-
|
|
1047
|
-
|
|
1048
|
-
##
|
|
1049
|
-
|
|
1050
|
-
-
|
|
1051
|
-
-
|
|
1052
|
-
-
|
|
1053
|
-
-
|
|
1054
|
-
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
##
|
|
1102
|
-
|
|
1103
|
-
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
-
|
|
1113
|
-
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
950
|
+
|
|
951
|
+
function generateSharedClaudeMd() {
|
|
952
|
+
return `@AGENTS.md
|
|
953
|
+
|
|
954
|
+
## Claude Code
|
|
955
|
+
|
|
956
|
+
This repository uses AGENTS.md as the shared cross-agent entry file. Follow the imported instructions and keep Claude-specific notes here only when they cannot apply to Codex or Antigravity.
|
|
957
|
+
`;
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
function generateSharedGeminiMd() {
|
|
961
|
+
return `# GEMINI.md
|
|
962
|
+
|
|
963
|
+
Antigravity entry file for this project.
|
|
964
|
+
|
|
965
|
+
Read AGENTS.md first, then follow the shared docs under .agent/docs/.
|
|
966
|
+
`;
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
function generateSharedCursorrules() {
|
|
970
|
+
return `# Cursor Rules
|
|
971
|
+
|
|
972
|
+
This repository uses AGENTS.md as the shared cross-agent entry file. Follow the instructions in AGENTS.md and keep Cursor-specific notes here only when they cannot apply to Codex, Antigravity, or Claude Code.
|
|
973
|
+
|
|
974
|
+
Read AGENTS.md first, then follow the shared docs under .agent/docs/.
|
|
975
|
+
`;
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
function resolveCommands(data) {
|
|
979
|
+
const frameworks = data.frameworks || [];
|
|
980
|
+
const primaryLang = data.primary_language || 'javascript';
|
|
981
|
+
const pkgManager = data.package_manager || 'npm';
|
|
982
|
+
const testFramework = data.test_framework || 'auto-detect';
|
|
983
|
+
|
|
984
|
+
const isPython = primaryLang === 'python';
|
|
985
|
+
const isGo = primaryLang === 'go';
|
|
986
|
+
const isRust = primaryLang === 'rust';
|
|
987
|
+
const isPhp = primaryLang === 'php';
|
|
988
|
+
|
|
989
|
+
let install = 'npm install';
|
|
990
|
+
let dev = 'npm run dev';
|
|
991
|
+
let build = 'npm run build';
|
|
992
|
+
let test = 'npm test';
|
|
993
|
+
let lint = 'npm run lint';
|
|
994
|
+
|
|
995
|
+
if (pkgManager === 'pnpm') { install = 'pnpm install'; dev = 'pnpm dev'; build = 'pnpm build'; test = 'pnpm test'; lint = 'pnpm lint'; }
|
|
996
|
+
else if (pkgManager === 'yarn') { install = 'yarn'; dev = 'yarn dev'; build = 'yarn build'; test = 'yarn test'; lint = 'yarn lint'; }
|
|
997
|
+
else if (pkgManager === 'bun') { install = 'bun install'; dev = 'bun dev'; build = 'bun run build'; test = 'bun test'; lint = 'bun run lint'; }
|
|
998
|
+
else if (isPython) { install = 'pip install -r requirements.txt'; dev = 'python manage.py runserver'; build = '# no build step'; test = 'pytest'; lint = 'ruff check .'; }
|
|
999
|
+
else if (isGo) { install = 'go mod download'; dev = 'go run .'; build = 'go build ./...'; test = 'go test ./...'; lint = 'golangci-lint run'; }
|
|
1000
|
+
else if (isRust) { install = 'cargo build'; dev = 'cargo run'; build = 'cargo build --release'; test = 'cargo test'; lint = 'cargo clippy'; }
|
|
1001
|
+
else if (isPhp) {
|
|
1002
|
+
install = 'composer install';
|
|
1003
|
+
build = '# no build step';
|
|
1004
|
+
test = testFramework === 'pest' ? './vendor/bin/pest' : './vendor/bin/phpunit';
|
|
1005
|
+
const isCakePHP = frameworks.some(f => f.toLowerCase().includes('cakephp'));
|
|
1006
|
+
const isSymfony = frameworks.some(f => f.toLowerCase().includes('symfony'));
|
|
1007
|
+
const isCodeIgniter = frameworks.some(f => f.toLowerCase().includes('codeigniter'));
|
|
1008
|
+
if (isCakePHP) {
|
|
1009
|
+
dev = 'bin/cake server';
|
|
1010
|
+
lint = './vendor/bin/phpcs';
|
|
1011
|
+
} else if (isSymfony) {
|
|
1012
|
+
dev = 'bin/console server:run';
|
|
1013
|
+
lint = './vendor/bin/phpcs';
|
|
1014
|
+
} else if (isCodeIgniter) {
|
|
1015
|
+
dev = 'php spark serve';
|
|
1016
|
+
lint = './vendor/bin/phpcs';
|
|
1017
|
+
} else {
|
|
1018
|
+
dev = 'php artisan serve';
|
|
1019
|
+
lint = 'php artisan pint';
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
if (testFramework === 'vitest') test = `${pkgManager === 'pnpm' ? 'pnpm' : pkgManager === 'yarn' ? 'yarn' : pkgManager === 'bun' ? 'bun run' : 'npx'} vitest`;
|
|
1024
|
+
else if (testFramework === 'jest') test = `${pkgManager === 'pnpm' ? 'pnpm' : pkgManager === 'yarn' ? 'yarn' : 'npx'} jest`;
|
|
1025
|
+
|
|
1026
|
+
return { install, dev, build, test, lint };
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
function generateProjectDoc(data) {
|
|
1030
|
+
const commands = resolveCommands(data);
|
|
1031
|
+
const agentRows = resolveAgentTable(data).map(([task, agent, skills]) => `| ${task} | \`${agent}\` | ${skills} |`).join('\n');
|
|
1032
|
+
const skillsList = resolveSkills(data).map(s => `- ${s}`).join('\n');
|
|
1033
|
+
const evidence = (data.scan_evidence || []).length > 0
|
|
1034
|
+
? (data.scan_evidence || []).map(line => `- ${line}`).join('\n')
|
|
1035
|
+
: '- TODO: refine scan evidence by inspecting the project.';
|
|
1036
|
+
|
|
1037
|
+
return `# Project Rules
|
|
1038
|
+
|
|
1039
|
+
Generated by thachvd-kit on ${new Date().toISOString().split('T')[0]}.
|
|
1040
|
+
|
|
1041
|
+
## Summary
|
|
1042
|
+
|
|
1043
|
+
- Name: ${data.project_name}
|
|
1044
|
+
- Description: ${data.description}
|
|
1045
|
+
- Type: ${data.project_type}
|
|
1046
|
+
- App root: ${data.app_root || '.'}
|
|
1047
|
+
|
|
1048
|
+
## Stack
|
|
1049
|
+
|
|
1050
|
+
- Language: ${data.primary_language}
|
|
1051
|
+
- Frameworks: ${(data.frameworks || []).join(', ') || 'none'}
|
|
1052
|
+
- Database: ${data.database || 'none'}
|
|
1053
|
+
- Infrastructure: ${(data.infrastructure || []).join(', ') || 'none'}
|
|
1054
|
+
- Package manager: ${data.package_manager || 'auto-detect'}
|
|
1055
|
+
- Test framework: ${data.test_framework || 'auto-detect'}
|
|
1056
|
+
|
|
1057
|
+
## Commands
|
|
1058
|
+
|
|
1059
|
+
- Install: \`${commands.install}\`
|
|
1060
|
+
- Dev: \`${commands.dev}\`
|
|
1061
|
+
- Build: \`${commands.build}\`
|
|
1062
|
+
- Test: \`${commands.test}\`
|
|
1063
|
+
- Lint: \`${commands.lint}\`
|
|
1064
|
+
|
|
1065
|
+
## Agent Routing
|
|
1066
|
+
|
|
1067
|
+
| Task Type | Agent | Primary Skills |
|
|
1068
|
+
|-----------|-------|----------------|
|
|
1069
|
+
${agentRows}
|
|
1070
|
+
|
|
1071
|
+
## Auto-Resolved Skills
|
|
1072
|
+
|
|
1073
|
+
${skillsList}
|
|
1074
|
+
|
|
1075
|
+
## Scan Evidence
|
|
1076
|
+
|
|
1077
|
+
${evidence}
|
|
1078
|
+
`;
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
function generateArchitectureDoc(data) {
|
|
1082
|
+
const appRootLine = data.app_root && data.app_root !== '.'
|
|
1083
|
+
? `- App root is currently detected as \`${data.app_root}\`.`
|
|
1084
|
+
: '- App root is the repository root unless refined below.';
|
|
1085
|
+
const evidence = (data.scan_evidence || []).length > 0
|
|
1086
|
+
? (data.scan_evidence || []).map(line => `- ${line}`).join('\n')
|
|
1087
|
+
: '- TODO: refine architecture by scanning source directories.';
|
|
1088
|
+
|
|
1089
|
+
return `# Architecture Notes
|
|
1090
|
+
|
|
1091
|
+
## Current Map
|
|
1092
|
+
|
|
1093
|
+
${appRootLine}
|
|
1094
|
+
- TODO: refine major directories and responsibilities.
|
|
1095
|
+
- TODO: refine main entry points, routing, state boundaries, and integration boundaries.
|
|
1096
|
+
|
|
1097
|
+
## Detected Evidence
|
|
1098
|
+
|
|
1099
|
+
${evidence}
|
|
1100
|
+
|
|
1101
|
+
## AI Maintenance Rule
|
|
1102
|
+
|
|
1103
|
+
Before non-trivial implementation work, inspect this file. If it is stale or still contains TODO items relevant to the task, update it from the code before editing product code.
|
|
1104
|
+
`;
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
function generateConventionsDoc(data) {
|
|
1108
|
+
return `# Coding Conventions
|
|
1109
|
+
|
|
1110
|
+
## Current Standards
|
|
1111
|
+
|
|
1112
|
+
- Maximum file length: ${data.max_file_lines || '300'} lines unless the existing project standard is stricter.
|
|
1113
|
+
- Code comments and identifiers should be written in English.
|
|
1114
|
+
- Keep changes scoped to the user request.
|
|
1115
|
+
- Prefer existing local patterns over introducing new abstractions.
|
|
1116
|
+
- TODO: refine naming, formatting, folder, API, state, styling, and testing conventions from the real codebase.
|
|
1117
|
+
|
|
1118
|
+
## Verification
|
|
1119
|
+
|
|
1120
|
+
- Run the focused test or lint command that matches the touched area.
|
|
1121
|
+
- If no automated check exists, document the manual verification performed.
|
|
1122
|
+
- Do not claim completion without verification evidence.
|
|
1123
|
+
`;
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1117
1126
|
function generateWorkflowDoc() {
|
|
1118
|
-
return `# Agent Workflow
|
|
1119
|
-
|
|
1120
|
-
## Before Every Task
|
|
1121
|
-
|
|
1127
|
+
return `# Agent Workflow
|
|
1128
|
+
|
|
1129
|
+
## Before Every Task
|
|
1130
|
+
|
|
1122
1131
|
1. Read AGENTS.md.
|
|
1123
1132
|
2. Read .agent/docs/project.md.
|
|
1124
1133
|
3. Classify the request: question, survey, simple fix, feature, refactor, debug, UI, security, or deploy.
|
|
@@ -1136,20 +1145,20 @@ function generateWorkflowDoc() {
|
|
|
1136
1145
|
- Run thachvd-kit --help to see common workflow and skill recommendations.
|
|
1137
1146
|
|
|
1138
1147
|
## Implementation Flow
|
|
1139
|
-
|
|
1140
|
-
1. State assumptions and success criteria when the task is not trivial.
|
|
1141
|
-
2. Inspect dependent files before editing.
|
|
1142
|
-
3. Make the smallest coherent change.
|
|
1143
|
-
4. Add or update focused tests when behavior changes.
|
|
1144
|
-
5. Run verification.
|
|
1145
|
-
6. Summarize changed files and verification evidence.
|
|
1146
|
-
|
|
1147
|
-
## When To Update Docs
|
|
1148
|
-
|
|
1149
|
-
- Update .agent/docs/architecture.md when structure, boundaries, or entry points change.
|
|
1150
|
-
- Update .agent/docs/conventions.md when repeated project patterns become clear.
|
|
1151
|
-
- Update .agent/docs/project.md when stack, scripts, app root, test tooling, or routing changes.
|
|
1152
|
-
- Keep AGENTS.md concise. Put project-specific detail in .agent/docs.
|
|
1148
|
+
|
|
1149
|
+
1. State assumptions and success criteria when the task is not trivial.
|
|
1150
|
+
2. Inspect dependent files before editing.
|
|
1151
|
+
3. Make the smallest coherent change.
|
|
1152
|
+
4. Add or update focused tests when behavior changes.
|
|
1153
|
+
5. Run verification.
|
|
1154
|
+
6. Summarize changed files and verification evidence.
|
|
1155
|
+
|
|
1156
|
+
## When To Update Docs
|
|
1157
|
+
|
|
1158
|
+
- Update .agent/docs/architecture.md when structure, boundaries, or entry points change.
|
|
1159
|
+
- Update .agent/docs/conventions.md when repeated project patterns become clear.
|
|
1160
|
+
- Update .agent/docs/project.md when stack, scripts, app root, test tooling, or routing changes.
|
|
1161
|
+
- Keep AGENTS.md concise. Put project-specific detail in .agent/docs.
|
|
1153
1162
|
`;
|
|
1154
1163
|
}
|
|
1155
1164
|
|
|
@@ -1199,6 +1208,12 @@ args = ["-y", "@upstash/context7-mcp"]
|
|
|
1199
1208
|
startup_timeout_sec = 20
|
|
1200
1209
|
tool_timeout_sec = 120
|
|
1201
1210
|
|
|
1211
|
+
[mcp_servers.filesystem]
|
|
1212
|
+
command = "npx"
|
|
1213
|
+
args = ["-y", "@modelcontextprotocol/server-filesystem", "<projectPath>"]
|
|
1214
|
+
startup_timeout_sec = 20
|
|
1215
|
+
tool_timeout_sec = 120
|
|
1216
|
+
|
|
1202
1217
|
[mcp_servers.playwright]
|
|
1203
1218
|
command = "npx"
|
|
1204
1219
|
args = ["-y", "@playwright/mcp"]
|
|
@@ -1243,6 +1258,10 @@ Gemini CLI / Antigravity \`mcp_config.json\` example:
|
|
|
1243
1258
|
"command": "npx",
|
|
1244
1259
|
"args": ["-y", "@upstash/context7-mcp"]
|
|
1245
1260
|
},
|
|
1261
|
+
"filesystem": {
|
|
1262
|
+
"command": "npx",
|
|
1263
|
+
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/project"]
|
|
1264
|
+
},
|
|
1246
1265
|
"playwright": {
|
|
1247
1266
|
"command": "npx",
|
|
1248
1267
|
"args": ["-y", "@playwright/mcp"]
|
|
@@ -1267,6 +1286,16 @@ Claude Code user config example:
|
|
|
1267
1286
|
"command": "codegraph",
|
|
1268
1287
|
"args": ["serve", "--mcp"]
|
|
1269
1288
|
},
|
|
1289
|
+
"context7": {
|
|
1290
|
+
"type": "stdio",
|
|
1291
|
+
"command": "npx",
|
|
1292
|
+
"args": ["-y", "@upstash/context7-mcp"]
|
|
1293
|
+
},
|
|
1294
|
+
"filesystem": {
|
|
1295
|
+
"type": "stdio",
|
|
1296
|
+
"command": "npx",
|
|
1297
|
+
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/project"]
|
|
1298
|
+
},
|
|
1270
1299
|
"playwright": {
|
|
1271
1300
|
"type": "stdio",
|
|
1272
1301
|
"command": "npx",
|
|
@@ -1278,7 +1307,7 @@ Claude Code user config example:
|
|
|
1278
1307
|
|
|
1279
1308
|
Common local path:
|
|
1280
1309
|
|
|
1281
|
-
- Claude Code: \`~/.claude.json\`
|
|
1310
|
+
- Claude Code: \`~/.claude.json\` or \`~/.claude/settings.json\`
|
|
1282
1311
|
|
|
1283
1312
|
## Native Skill Folders
|
|
1284
1313
|
|
|
@@ -1298,39 +1327,39 @@ Recommended candidates to copy first:
|
|
|
1298
1327
|
- Stack-specific skills listed in \`.agent/docs/project.md\`
|
|
1299
1328
|
`;
|
|
1300
1329
|
}
|
|
1301
|
-
|
|
1302
|
-
// --- Agent Folder Copy ---
|
|
1303
|
-
|
|
1330
|
+
|
|
1331
|
+
// --- Agent Folder Copy ---
|
|
1332
|
+
|
|
1304
1333
|
function copyAgentFolder() {
|
|
1305
|
-
const srcAgent = path.join(sourceDir, '.agent');
|
|
1306
|
-
if (!fs.existsSync(srcAgent)) return { copied: 0, skipped: 0 };
|
|
1307
|
-
|
|
1308
|
-
const destAgent = path.join(targetDir, '.agent');
|
|
1309
|
-
let copied = 0;
|
|
1310
|
-
let skipped = 0;
|
|
1311
|
-
|
|
1312
|
-
function copyDir(src, dest) {
|
|
1313
|
-
fs.mkdirSync(dest, { recursive: true });
|
|
1314
|
-
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
1315
|
-
const srcPath = path.join(src, entry.name);
|
|
1316
|
-
const destPath = path.join(dest, entry.name);
|
|
1317
|
-
const relativeSrc = path.relative(srcAgent, srcPath).split(path.sep).join('/');
|
|
1318
|
-
if (relativeSrc === 'docs' || relativeSrc.startsWith('docs/')) {
|
|
1319
|
-
continue;
|
|
1320
|
-
}
|
|
1321
|
-
if (entry.isDirectory()) {
|
|
1322
|
-
copyDir(srcPath, destPath);
|
|
1323
|
-
} else {
|
|
1324
|
-
if (fs.existsSync(destPath)) {
|
|
1325
|
-
skipped++;
|
|
1326
|
-
} else {
|
|
1327
|
-
fs.copyFileSync(srcPath, destPath);
|
|
1328
|
-
copied++;
|
|
1329
|
-
}
|
|
1330
|
-
}
|
|
1331
|
-
}
|
|
1332
|
-
}
|
|
1333
|
-
|
|
1334
|
+
const srcAgent = path.join(sourceDir, '.agent');
|
|
1335
|
+
if (!fs.existsSync(srcAgent)) return { copied: 0, skipped: 0 };
|
|
1336
|
+
|
|
1337
|
+
const destAgent = path.join(targetDir, '.agent');
|
|
1338
|
+
let copied = 0;
|
|
1339
|
+
let skipped = 0;
|
|
1340
|
+
|
|
1341
|
+
function copyDir(src, dest) {
|
|
1342
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
1343
|
+
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
1344
|
+
const srcPath = path.join(src, entry.name);
|
|
1345
|
+
const destPath = path.join(dest, entry.name);
|
|
1346
|
+
const relativeSrc = path.relative(srcAgent, srcPath).split(path.sep).join('/');
|
|
1347
|
+
if (relativeSrc === 'docs' || relativeSrc.startsWith('docs/')) {
|
|
1348
|
+
continue;
|
|
1349
|
+
}
|
|
1350
|
+
if (entry.isDirectory()) {
|
|
1351
|
+
copyDir(srcPath, destPath);
|
|
1352
|
+
} else {
|
|
1353
|
+
if (fs.existsSync(destPath)) {
|
|
1354
|
+
skipped++;
|
|
1355
|
+
} else {
|
|
1356
|
+
fs.copyFileSync(srcPath, destPath);
|
|
1357
|
+
copied++;
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1362
|
+
|
|
1334
1363
|
copyDir(srcAgent, destAgent);
|
|
1335
1364
|
return { copied, skipped };
|
|
1336
1365
|
}
|
|
@@ -1437,7 +1466,7 @@ function writeJsonFile(filePath, data) {
|
|
|
1437
1466
|
fs.writeFileSync(filePath, JSON.stringify(data, null, 2) + '\n', 'utf8');
|
|
1438
1467
|
}
|
|
1439
1468
|
|
|
1440
|
-
function mergeMcpJson(filePath, withType = false
|
|
1469
|
+
function mergeMcpJson(filePath, withType = false) {
|
|
1441
1470
|
const data = readJsonFile(filePath);
|
|
1442
1471
|
if (data === null) {
|
|
1443
1472
|
return { ok: false, message: `${filePath} is not valid JSON; skipped` };
|
|
@@ -1445,14 +1474,49 @@ function mergeMcpJson(filePath, withType = false, includeContext7 = false) {
|
|
|
1445
1474
|
data.mcpServers = data.mcpServers || {};
|
|
1446
1475
|
const baseServers = {
|
|
1447
1476
|
codegraph: { command: 'codegraph', args: ['serve', '--mcp'] },
|
|
1448
|
-
playwright: { command: 'npx', args: ['-y', '@playwright/mcp'] }
|
|
1477
|
+
playwright: { command: 'npx', args: ['-y', '@playwright/mcp'] },
|
|
1478
|
+
context7: { command: 'npx', args: ['-y', '@upstash/context7-mcp'] },
|
|
1479
|
+
filesystem: { command: 'npx', args: ['-y', '@modelcontextprotocol/server-filesystem', targetDir.replace(/\\/g, '/')] }
|
|
1449
1480
|
};
|
|
1450
|
-
if (
|
|
1451
|
-
|
|
1481
|
+
if (data.permissions && Array.isArray(data.permissions.allow)) {
|
|
1482
|
+
const requiredPermissions = [
|
|
1483
|
+
"mcp__filesystem__read_file",
|
|
1484
|
+
"mcp__filesystem__read_multiple_files",
|
|
1485
|
+
"mcp__filesystem__list_directory",
|
|
1486
|
+
"mcp__filesystem__directory_tree",
|
|
1487
|
+
"mcp__filesystem__search_files",
|
|
1488
|
+
"mcp__filesystem__get_file_info",
|
|
1489
|
+
"mcp__filesystem__write_file",
|
|
1490
|
+
"mcp__context7__resolve-library-id",
|
|
1491
|
+
"mcp__context7__query-docs"
|
|
1492
|
+
];
|
|
1493
|
+
for (const perm of requiredPermissions) {
|
|
1494
|
+
if (!data.permissions.allow.includes(perm)) {
|
|
1495
|
+
data.permissions.allow.push(perm);
|
|
1496
|
+
}
|
|
1497
|
+
}
|
|
1452
1498
|
}
|
|
1453
1499
|
for (const [name, server] of Object.entries(baseServers)) {
|
|
1454
1500
|
if (!data.mcpServers[name]) {
|
|
1455
1501
|
data.mcpServers[name] = withType ? { type: 'stdio', ...server } : server;
|
|
1502
|
+
} else if (name === 'filesystem') {
|
|
1503
|
+
const fsServer = data.mcpServers[name];
|
|
1504
|
+
if (fsServer && Array.isArray(fsServer.args)) {
|
|
1505
|
+
// If it points to non-existent AppData roaming file, fix it to use npx
|
|
1506
|
+
const isLegacyNode = fsServer.command === 'node' && fsServer.args[0] && fsServer.args[0].includes('server-filesystem');
|
|
1507
|
+
if (isLegacyNode) {
|
|
1508
|
+
fsServer.command = 'npx';
|
|
1509
|
+
fsServer.args[0] = '-y';
|
|
1510
|
+
fsServer.args.splice(1, 0, '@modelcontextprotocol/server-filesystem');
|
|
1511
|
+
}
|
|
1512
|
+
const normalizedTarget = targetDir.replace(/\\/g, '/');
|
|
1513
|
+
const hasTarget = fsServer.args.some(arg => {
|
|
1514
|
+
return typeof arg === 'string' && (arg.replace(/\\/g, '/').toLowerCase() === normalizedTarget.toLowerCase());
|
|
1515
|
+
});
|
|
1516
|
+
if (!hasTarget) {
|
|
1517
|
+
fsServer.args.push(normalizedTarget);
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1456
1520
|
}
|
|
1457
1521
|
}
|
|
1458
1522
|
writeJsonFile(filePath, data);
|
|
@@ -1464,12 +1528,21 @@ function appendMcpTomlIfMissing(filePath) {
|
|
|
1464
1528
|
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
1465
1529
|
const existing = fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf8') : '';
|
|
1466
1530
|
const blocks = [];
|
|
1531
|
+
const normalizedTarget = targetDir.replace(/\\/g, '/');
|
|
1467
1532
|
if (!/\[mcp_servers\.context7\]/.test(existing)) {
|
|
1468
1533
|
blocks.push(`[mcp_servers.context7]
|
|
1469
1534
|
command = "npx"
|
|
1470
1535
|
args = ["-y", "@upstash/context7-mcp"]
|
|
1471
1536
|
startup_timeout_sec = 20
|
|
1472
1537
|
tool_timeout_sec = 120
|
|
1538
|
+
`);
|
|
1539
|
+
}
|
|
1540
|
+
if (!/\[mcp_servers\.filesystem\]/.test(existing)) {
|
|
1541
|
+
blocks.push(`[mcp_servers.filesystem]
|
|
1542
|
+
command = "npx"
|
|
1543
|
+
args = ["-y", "@modelcontextprotocol/server-filesystem", "${normalizedTarget}"]
|
|
1544
|
+
startup_timeout_sec = 20
|
|
1545
|
+
tool_timeout_sec = 120
|
|
1473
1546
|
`);
|
|
1474
1547
|
}
|
|
1475
1548
|
if (!/\[mcp_servers\.codegraph\]/.test(existing)) {
|
|
@@ -1493,7 +1566,7 @@ tool_timeout_sec = 120
|
|
|
1493
1566
|
}
|
|
1494
1567
|
const separator = existing && !existing.endsWith('\n') ? '\n\n' : existing ? '\n' : '';
|
|
1495
1568
|
fs.writeFileSync(filePath, existing + separator + blocks.join('\n'), 'utf8');
|
|
1496
|
-
return { ok: true, message: `configured context7, codegraph, playwright MCP in ${filePath}` };
|
|
1569
|
+
return { ok: true, message: `configured context7, filesystem, codegraph, playwright MCP in ${filePath}` };
|
|
1497
1570
|
}
|
|
1498
1571
|
|
|
1499
1572
|
function setupMcpServers() {
|
|
@@ -1504,45 +1577,48 @@ function setupMcpServers() {
|
|
|
1504
1577
|
if (codexConfig) results.push(appendMcpTomlIfMissing(codexConfig));
|
|
1505
1578
|
|
|
1506
1579
|
const geminiConfig = homePath('.gemini', 'config', 'mcp_config.json');
|
|
1507
|
-
if (geminiConfig) results.push(mergeMcpJson(geminiConfig, false
|
|
1580
|
+
if (geminiConfig) results.push(mergeMcpJson(geminiConfig, false));
|
|
1508
1581
|
|
|
1509
1582
|
const antigravityIdeConfig = homePath('.gemini', 'antigravity-ide', 'mcp_config.json');
|
|
1510
|
-
if (antigravityIdeConfig) results.push(mergeMcpJson(antigravityIdeConfig, false
|
|
1583
|
+
if (antigravityIdeConfig) results.push(mergeMcpJson(antigravityIdeConfig, false));
|
|
1511
1584
|
|
|
1512
1585
|
const antigravityConfig = homePath('.gemini', 'antigravity', 'mcp_config.json');
|
|
1513
1586
|
if (antigravityConfig && fs.existsSync(path.dirname(antigravityConfig))) {
|
|
1514
|
-
results.push(mergeMcpJson(antigravityConfig, false
|
|
1587
|
+
results.push(mergeMcpJson(antigravityConfig, false));
|
|
1515
1588
|
}
|
|
1516
1589
|
|
|
1517
1590
|
const claudeConfig = homePath('.claude.json');
|
|
1518
1591
|
if (claudeConfig) results.push(mergeMcpJson(claudeConfig, true));
|
|
1519
1592
|
|
|
1593
|
+
const claudeSettings = homePath('.claude', 'settings.json');
|
|
1594
|
+
if (claudeSettings) results.push(mergeMcpJson(claudeSettings, true));
|
|
1595
|
+
|
|
1520
1596
|
return results;
|
|
1521
1597
|
}
|
|
1522
1598
|
|
|
1523
1599
|
// --- Main CLI ---
|
|
1524
|
-
|
|
1600
|
+
|
|
1525
1601
|
async function main() {
|
|
1526
|
-
const rawArgs = process.argv.slice(2);
|
|
1527
|
-
const command = rawArgs[0] && !rawArgs[0].startsWith('-') ? rawArgs[0] : 'init';
|
|
1528
|
-
const args = command === 'init' ? rawArgs.slice(rawArgs[0] === 'init' ? 1 : 0) : rawArgs.slice(1);
|
|
1529
|
-
|
|
1530
|
-
if (rawArgs.includes('--version') || rawArgs.includes('-v')) {
|
|
1531
|
-
console.log(packageJson.version);
|
|
1532
|
-
return;
|
|
1533
|
-
}
|
|
1534
|
-
|
|
1535
|
-
if (rawArgs.includes('--help') || rawArgs.includes('-h')) {
|
|
1536
|
-
printHelp();
|
|
1537
|
-
return;
|
|
1538
|
-
}
|
|
1539
|
-
|
|
1540
|
-
if (command !== 'init') {
|
|
1541
|
-
console.error(pc.red(`Unknown command: ${command}`));
|
|
1542
|
-
printHelp();
|
|
1543
|
-
process.exit(1);
|
|
1544
|
-
}
|
|
1545
|
-
|
|
1602
|
+
const rawArgs = process.argv.slice(2);
|
|
1603
|
+
const command = rawArgs[0] && !rawArgs[0].startsWith('-') ? rawArgs[0] : 'init';
|
|
1604
|
+
const args = command === 'init' ? rawArgs.slice(rawArgs[0] === 'init' ? 1 : 0) : rawArgs.slice(1);
|
|
1605
|
+
|
|
1606
|
+
if (rawArgs.includes('--version') || rawArgs.includes('-v')) {
|
|
1607
|
+
console.log(packageJson.version);
|
|
1608
|
+
return;
|
|
1609
|
+
}
|
|
1610
|
+
|
|
1611
|
+
if (rawArgs.includes('--help') || rawArgs.includes('-h')) {
|
|
1612
|
+
printHelp();
|
|
1613
|
+
return;
|
|
1614
|
+
}
|
|
1615
|
+
|
|
1616
|
+
if (command !== 'init') {
|
|
1617
|
+
console.error(pc.red(`Unknown command: ${command}`));
|
|
1618
|
+
printHelp();
|
|
1619
|
+
process.exit(1);
|
|
1620
|
+
}
|
|
1621
|
+
|
|
1546
1622
|
const assumeYes = args.includes('--yes') || args.includes('-y');
|
|
1547
1623
|
const skipMcpSetup = args.includes('--no-setup-mcp') || process.env.THACHVD_KIT_SKIP_MCP_SETUP === '1';
|
|
1548
1624
|
|
|
@@ -1579,17 +1655,17 @@ async function main() {
|
|
|
1579
1655
|
test_framework: scanned?.test_framework || 'auto-detect',
|
|
1580
1656
|
max_file_lines: scanned?.max_file_lines || '300'
|
|
1581
1657
|
};
|
|
1582
|
-
|
|
1583
|
-
data.database = data.database || scanned?.database || 'none';
|
|
1584
|
-
data.uses_docker = typeof data.uses_docker === 'boolean' ? data.uses_docker : (scanned?.uses_docker ?? true);
|
|
1585
|
-
data.cloud = data.cloud || scanned?.cloud || 'none';
|
|
1586
|
-
data.package_manager = data.package_manager || scanned?.package_manager || 'auto-detect';
|
|
1587
|
-
data.test_framework = data.test_framework || scanned?.test_framework || 'auto-detect';
|
|
1588
|
-
data.max_file_lines = data.max_file_lines || scanned?.max_file_lines || '300';
|
|
1589
|
-
data.framework_details = scanned?.framework_details || [];
|
|
1590
|
-
data.scan_evidence = scanned?.scan_evidence || [];
|
|
1591
|
-
data.app_root = scanned?.app_root || '.';
|
|
1592
|
-
|
|
1658
|
+
|
|
1659
|
+
data.database = data.database || scanned?.database || 'none';
|
|
1660
|
+
data.uses_docker = typeof data.uses_docker === 'boolean' ? data.uses_docker : (scanned?.uses_docker ?? true);
|
|
1661
|
+
data.cloud = data.cloud || scanned?.cloud || 'none';
|
|
1662
|
+
data.package_manager = data.package_manager || scanned?.package_manager || 'auto-detect';
|
|
1663
|
+
data.test_framework = data.test_framework || scanned?.test_framework || 'auto-detect';
|
|
1664
|
+
data.max_file_lines = data.max_file_lines || scanned?.max_file_lines || '300';
|
|
1665
|
+
data.framework_details = scanned?.framework_details || [];
|
|
1666
|
+
data.scan_evidence = scanned?.scan_evidence || [];
|
|
1667
|
+
data.app_root = scanned?.app_root || '.';
|
|
1668
|
+
|
|
1593
1669
|
data.infrastructure = [];
|
|
1594
1670
|
if (data.uses_docker) data.infrastructure.push('docker');
|
|
1595
1671
|
if (data.cloud !== 'none') data.infrastructure.push(data.cloud);
|
|
@@ -1597,13 +1673,13 @@ async function main() {
|
|
|
1597
1673
|
const shouldSetupMcp = !skipMcpSetup;
|
|
1598
1674
|
|
|
1599
1675
|
console.log(`\n${pc.bold(pc.cyan('Generating Files'))}`);
|
|
1600
|
-
|
|
1601
|
-
// Shared entry files are written after the .agent folder is available.
|
|
1602
|
-
|
|
1603
|
-
// Copy .agent folder
|
|
1604
|
-
const { copied, skipped } = copyAgentFolder();
|
|
1605
|
-
if (copied > 0) {
|
|
1606
|
-
console.log(` ${pc.green('OK')} Copied ${pc.bold('.agent/')} (${copied} file${copied !== 1 ? 's' : ''} added${skipped > 0 ? `, ${skipped} skipped` : ''})`);
|
|
1676
|
+
|
|
1677
|
+
// Shared entry files are written after the .agent folder is available.
|
|
1678
|
+
|
|
1679
|
+
// Copy .agent folder
|
|
1680
|
+
const { copied, skipped } = copyAgentFolder();
|
|
1681
|
+
if (copied > 0) {
|
|
1682
|
+
console.log(` ${pc.green('OK')} Copied ${pc.bold('.agent/')} (${copied} file${copied !== 1 ? 's' : ''} added${skipped > 0 ? `, ${skipped} skipped` : ''})`);
|
|
1607
1683
|
} else if (skipped > 0) {
|
|
1608
1684
|
console.log(` ${pc.yellow('~')} ${pc.bold('.agent/')} already exists - ${skipped} file${skipped !== 1 ? 's' : ''} skipped (no overwrite)`);
|
|
1609
1685
|
}
|
|
@@ -1617,16 +1693,17 @@ async function main() {
|
|
|
1617
1693
|
|
|
1618
1694
|
|
|
1619
1695
|
const generatedFiles = [
|
|
1620
|
-
['AGENTS.md', generateSharedAgentsMd(data)],
|
|
1621
|
-
['CLAUDE.md', generateSharedClaudeMd()],
|
|
1622
|
-
['GEMINI.md', generateSharedGeminiMd()],
|
|
1623
|
-
[
|
|
1696
|
+
['AGENTS.md', generateSharedAgentsMd(data)],
|
|
1697
|
+
['CLAUDE.md', generateSharedClaudeMd()],
|
|
1698
|
+
['GEMINI.md', generateSharedGeminiMd()],
|
|
1699
|
+
['.cursorrules', generateSharedCursorrules()],
|
|
1700
|
+
[path.join('.agent', 'docs', 'project.md'), generateProjectDoc(data)],
|
|
1624
1701
|
[path.join('.agent', 'docs', 'architecture.md'), generateArchitectureDoc(data)],
|
|
1625
1702
|
[path.join('.agent', 'docs', 'conventions.md'), generateConventionsDoc(data)],
|
|
1626
1703
|
[path.join('.agent', 'docs', 'workflow.md'), generateWorkflowDoc()],
|
|
1627
1704
|
[path.join('.agent', 'docs', 'tooling.md'), generateToolingDoc(data)]
|
|
1628
1705
|
];
|
|
1629
|
-
|
|
1706
|
+
|
|
1630
1707
|
for (const [relativePath, content] of generatedFiles) {
|
|
1631
1708
|
const wrote = await writeGeneratedFile(relativePath, content, assumeYes);
|
|
1632
1709
|
if (wrote) console.log(` ${pc.green('OK')} Generated ${pc.bold(relativePath)}`);
|
|
@@ -1642,14 +1719,15 @@ async function main() {
|
|
|
1642
1719
|
}
|
|
1643
1720
|
|
|
1644
1721
|
console.log(`\n${pc.bold(pc.green('Done!'))}
|
|
1645
|
-
|
|
1646
|
-
${pc.bold('Project:')} ${data.project_name}
|
|
1647
|
-
${pc.bold('Stack:')} ${data.primary_language} | ${(data.frameworks || []).join(', ') || 'no framework'}
|
|
1648
|
-
|
|
1649
|
-
${pc.bold('Generated:')}
|
|
1650
|
-
- ${pc.bold('AGENTS.md')} shared entry for Codex, Antigravity,
|
|
1651
|
-
- ${pc.bold('CLAUDE.md')} Claude Code entry that imports AGENTS.md
|
|
1722
|
+
|
|
1723
|
+
${pc.bold('Project:')} ${data.project_name}
|
|
1724
|
+
${pc.bold('Stack:')} ${data.primary_language} | ${(data.frameworks || []).join(', ') || 'no framework'}
|
|
1725
|
+
|
|
1726
|
+
${pc.bold('Generated:')}
|
|
1727
|
+
- ${pc.bold('AGENTS.md')} shared entry for Codex, Antigravity, Claude Code, and Cursor
|
|
1728
|
+
- ${pc.bold('CLAUDE.md')} Claude Code entry that imports AGENTS.md
|
|
1652
1729
|
- ${pc.bold('GEMINI.md')} Antigravity entry
|
|
1730
|
+
- ${pc.bold('.cursorrules')} Cursor entry
|
|
1653
1731
|
- ${pc.bold('.agent/docs/')} scan-based project rules
|
|
1654
1732
|
- ${pc.bold('.agent/')} skills, workflows, agents, and rules
|
|
1655
1733
|
- ${pc.bold('~/.codex/skills/')} selected Codex skills installed globally (visible in $ menu)
|
|
@@ -1664,22 +1742,23 @@ async function main() {
|
|
|
1664
1742
|
|
|
1665
1743
|
${pc.bold('Next steps:')}
|
|
1666
1744
|
1. Copy the prompt below into your AI editor and describe what the project does
|
|
1667
|
-
2. Commit ${pc.bold('AGENTS.md')}, ${pc.bold('CLAUDE.md')}, ${pc.bold('GEMINI.md')}, and ${pc.bold('.agent/')}
|
|
1668
|
-
3. Open the project in Codex, Antigravity,
|
|
1745
|
+
2. Commit ${pc.bold('AGENTS.md')}, ${pc.bold('CLAUDE.md')}, ${pc.bold('GEMINI.md')}, ${pc.bold('.cursorrules')}, and ${pc.bold('.agent/')}
|
|
1746
|
+
3. Open the project in Codex, Antigravity, Claude Code, or Cursor
|
|
1669
1747
|
|
|
1670
1748
|
${pc.bold('Copy this prompt into your AI editor:')}
|
|
1671
1749
|
${pc.dim('---')}
|
|
1672
1750
|
Read AGENTS.md and all files under .agent/docs/.
|
|
1673
1751
|
Ask me what this project does and any important conventions I want preserved.
|
|
1674
1752
|
Then scan this repository.
|
|
1675
|
-
Update AGENTS.md and .agent/docs/project.md, .agent/docs/architecture.md, .agent/docs/conventions.md, .agent/docs/workflow.md, and .agent/docs/tooling.md with factual project-specific rules.
|
|
1753
|
+
Update AGENTS.md, .cursorrules and .agent/docs/project.md, .agent/docs/architecture.md, .agent/docs/conventions.md, .agent/docs/workflow.md, and .agent/docs/tooling.md with factual project-specific rules.
|
|
1676
1754
|
Do not implement product code.
|
|
1677
1755
|
Remove TODO: refine only when backed by evidence from the codebase.
|
|
1678
1756
|
${pc.dim('---')}
|
|
1679
|
-
`);
|
|
1680
|
-
}
|
|
1757
|
+
`);
|
|
1758
|
+
}
|
|
1759
|
+
|
|
1760
|
+
main().catch(err => {
|
|
1761
|
+
console.error(pc.red('\nError during init:'), err);
|
|
1762
|
+
process.exit(1);
|
|
1763
|
+
});
|
|
1681
1764
|
|
|
1682
|
-
main().catch(err => {
|
|
1683
|
-
console.error(pc.red('\nError during init:'), err);
|
|
1684
|
-
process.exit(1);
|
|
1685
|
-
});
|