thachvd-kit 1.0.5 → 1.0.7
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 +1 -0
- package/bin/cli.js +116 -18
- package/package.json +1 -1
- package/scripts/init.py +83 -10
package/README.md
CHANGED
|
@@ -18,6 +18,7 @@ npx github:thachvd/thachvd-kit init
|
|
|
18
18
|
The interactive wizard will first ask whether this is a new project or an existing one.
|
|
19
19
|
If it is an existing project, it can scan the current codebase to prefill `PROJECT_CONTEXT.md`, or let you enter everything manually.
|
|
20
20
|
The scan mode uses evidence-based detectors and shows why a framework was inferred, so you can quickly confirm or correct it.
|
|
21
|
+
After init, you can also generate an AI refinement prompt to let your editor/agent deepen the project context.
|
|
21
22
|
|
|
22
23
|
```bash
|
|
23
24
|
thachvd-kit init --scan
|
package/bin/cli.js
CHANGED
|
@@ -842,9 +842,73 @@ Stack: ${data.primary_language} | ${(data.frameworks || []).join(', ')}
|
|
|
842
842
|
- \`/test\` — Run test suite
|
|
843
843
|
- \`/deploy\` — Deploy checklist
|
|
844
844
|
|
|
845
|
-
See PROJECT_CONTEXT.md for full agent routing table.
|
|
846
|
-
`;
|
|
847
|
-
}
|
|
845
|
+
See PROJECT_CONTEXT.md for full agent routing table.
|
|
846
|
+
`;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
function generateAiContextRefinementPrompt(data) {
|
|
850
|
+
const evidence = (data.scan_evidence || []).length > 0
|
|
851
|
+
? (data.scan_evidence || []).map(line => `- ${line}`).join('\n')
|
|
852
|
+
: '- No scan evidence was captured during init.';
|
|
853
|
+
|
|
854
|
+
return `# AI Context Refinement
|
|
855
|
+
|
|
856
|
+
Use this prompt in your AI editor after \`thachvd-kit init\`.
|
|
857
|
+
|
|
858
|
+
## Goal
|
|
859
|
+
|
|
860
|
+
Refine \`PROJECT_CONTEXT.md\` so it reflects the real project more accurately than the baseline init scan.
|
|
861
|
+
|
|
862
|
+
## Current Baseline
|
|
863
|
+
|
|
864
|
+
- Project: ${data.project_name}
|
|
865
|
+
- Type: ${data.project_type}
|
|
866
|
+
- Stack: ${data.primary_language} | ${(data.frameworks || []).join(', ') || 'no framework'}
|
|
867
|
+
- Database: ${data.database || 'none'}
|
|
868
|
+
- Infra: ${(data.infrastructure || []).join(', ') || 'none'}
|
|
869
|
+
|
|
870
|
+
## Scan Evidence
|
|
871
|
+
|
|
872
|
+
${evidence}
|
|
873
|
+
|
|
874
|
+
## Instructions For The AI Agent
|
|
875
|
+
|
|
876
|
+
1. Read \`PROJECT_CONTEXT.md\` first.
|
|
877
|
+
2. Inspect the project selectively to improve factual accuracy.
|
|
878
|
+
3. Prioritize:
|
|
879
|
+
- real database/config detection
|
|
880
|
+
- domain/capability inference
|
|
881
|
+
- architecture notes
|
|
882
|
+
- more accurate auto-resolved skills
|
|
883
|
+
- important project-specific constraints
|
|
884
|
+
4. Update \`PROJECT_CONTEXT.md\` directly.
|
|
885
|
+
5. Distinguish facts from inferences when uncertain.
|
|
886
|
+
6. Do not implement product code in this pass. Only refine project context.
|
|
887
|
+
|
|
888
|
+
## Suggested Files To Inspect
|
|
889
|
+
|
|
890
|
+
- Root manifests: \`package.json\`, \`composer.json\`, \`Cargo.toml\`, \`pyproject.toml\`
|
|
891
|
+
- Infrastructure/config: Docker, CI, env, framework config files
|
|
892
|
+
- Database config and models
|
|
893
|
+
- Main app entry points, routing, controllers/services
|
|
894
|
+
- README and existing documentation
|
|
895
|
+
|
|
896
|
+
## Desired Improvements
|
|
897
|
+
|
|
898
|
+
- Correct the \`database\` field if config files reveal the real DB.
|
|
899
|
+
- Add architecture notes that explain the actual structure.
|
|
900
|
+
- Infer domain capabilities such as scraping, browser automation, external API integrations, queues, workers, etc.
|
|
901
|
+
- Expand auto-resolved skills when there is clear evidence in the codebase.
|
|
902
|
+
- Add caveats or assumptions if parts of the stack are still uncertain.
|
|
903
|
+
|
|
904
|
+
## Completion Standard
|
|
905
|
+
|
|
906
|
+
When done, summarize:
|
|
907
|
+
- what was corrected
|
|
908
|
+
- what is still inferred
|
|
909
|
+
- which files provided the strongest evidence
|
|
910
|
+
`;
|
|
911
|
+
}
|
|
848
912
|
|
|
849
913
|
// --- Main CLI ---
|
|
850
914
|
|
|
@@ -924,6 +988,8 @@ async function main() {
|
|
|
924
988
|
}
|
|
925
989
|
|
|
926
990
|
const scanned = useScan ? scanProject() : null;
|
|
991
|
+
let reviewScannedFields = !useScan;
|
|
992
|
+
let requestAiRefinement = false;
|
|
927
993
|
|
|
928
994
|
if (useScan) {
|
|
929
995
|
console.log(`${pc.bold(' Scan result:')} ${scanned.primary_language} | ${scanned.frameworks.join(', ') || 'no framework'}`);
|
|
@@ -933,20 +999,34 @@ async function main() {
|
|
|
933
999
|
scanned.scan_evidence.forEach(line => console.log(` · ${line}`));
|
|
934
1000
|
console.log('');
|
|
935
1001
|
}
|
|
1002
|
+
|
|
1003
|
+
if (!assumeYes) {
|
|
1004
|
+
const scanAction = await askQuestions({
|
|
1005
|
+
type: 'select',
|
|
1006
|
+
name: 'scan_action',
|
|
1007
|
+
message: 'Use detected context as-is or review fields manually?',
|
|
1008
|
+
choices: [
|
|
1009
|
+
{ title: 'Use detected context', value: 'accept' },
|
|
1010
|
+
{ title: 'Review detected fields', value: 'review' }
|
|
1011
|
+
],
|
|
1012
|
+
initial: 0
|
|
1013
|
+
});
|
|
1014
|
+
reviewScannedFields = scanAction.scan_action === 'review';
|
|
1015
|
+
}
|
|
936
1016
|
}
|
|
937
1017
|
|
|
938
1018
|
const { project_name, description, project_type } = await askQuestions([
|
|
939
|
-
{ type: assumeYes ? null : 'text', name: 'project_name', message: 'Project name:', initial: scanned?.project_name || path.basename(targetDir) },
|
|
940
|
-
{ type: assumeYes ? null : 'text', name: 'description', message: 'Short description:', initial: scanned?.description || 'A software project' },
|
|
1019
|
+
{ type: assumeYes || !reviewScannedFields ? null : 'text', name: 'project_name', message: 'Project name:', initial: scanned?.project_name || path.basename(targetDir) },
|
|
1020
|
+
{ type: assumeYes || !reviewScannedFields ? null : 'text', name: 'description', message: 'Short description:', initial: scanned?.description || 'A software project' },
|
|
941
1021
|
{
|
|
942
|
-
type: assumeYes ? null : 'select', name: 'project_type', message: 'Project type:',
|
|
1022
|
+
type: assumeYes || !reviewScannedFields ? null : 'select', name: 'project_type', message: 'Project type:',
|
|
943
1023
|
choices: PROJECT_TYPE_CHOICES.map(value => ({ title: value, value })),
|
|
944
1024
|
initial: Math.max(PROJECT_TYPE_CHOICES.indexOf(scanned?.project_type || 'web-app'), 0)
|
|
945
1025
|
}
|
|
946
1026
|
]);
|
|
947
1027
|
|
|
948
1028
|
const { primary_language } = await askQuestions({
|
|
949
|
-
type: assumeYes ? null : 'select',
|
|
1029
|
+
type: assumeYes || !reviewScannedFields ? null : 'select',
|
|
950
1030
|
name: 'primary_language',
|
|
951
1031
|
message: 'Primary language:',
|
|
952
1032
|
choices: LANGUAGE_CHOICES.map(l => ({ title: l, value: l })),
|
|
@@ -954,7 +1034,7 @@ async function main() {
|
|
|
954
1034
|
});
|
|
955
1035
|
|
|
956
1036
|
const { frameworks } = await askQuestions({
|
|
957
|
-
type: assumeYes ? null : 'multiselect',
|
|
1037
|
+
type: assumeYes || !reviewScannedFields ? null : 'multiselect',
|
|
958
1038
|
name: 'frameworks',
|
|
959
1039
|
message: 'Frameworks (Space to select, Enter to confirm):',
|
|
960
1040
|
choices: FRAMEWORK_CHOICES.map(f => ({ title: f, value: f, selected: (scanned?.frameworks || []).includes(f) })),
|
|
@@ -963,13 +1043,13 @@ async function main() {
|
|
|
963
1043
|
|
|
964
1044
|
const dbAndInfra = await askQuestions([
|
|
965
1045
|
{
|
|
966
|
-
type: assumeYes ? null : 'select', name: 'database', message: 'Database / ORM:',
|
|
1046
|
+
type: assumeYes || !reviewScannedFields ? null : 'select', name: 'database', message: 'Database / ORM:',
|
|
967
1047
|
choices: DATABASE_CHOICES.map(d => ({ title: d, value: d })),
|
|
968
1048
|
initial: Math.max(DATABASE_CHOICES.indexOf(scanned?.database || 'none'), 0)
|
|
969
1049
|
},
|
|
970
|
-
{ type: assumeYes ? null : 'confirm', name: 'uses_docker', message: 'Uses Docker / Docker Compose?', initial: scanned?.uses_docker ?? true },
|
|
1050
|
+
{ type: assumeYes || !reviewScannedFields ? null : 'confirm', name: 'uses_docker', message: 'Uses Docker / Docker Compose?', initial: scanned?.uses_docker ?? true },
|
|
971
1051
|
{
|
|
972
|
-
type: assumeYes ? null : 'select', name: 'cloud', message: 'Cloud Provider:',
|
|
1052
|
+
type: assumeYes || !reviewScannedFields ? null : 'select', name: 'cloud', message: 'Cloud Provider:',
|
|
973
1053
|
choices: CLOUD_CHOICES.map(c => ({ title: c, value: c })),
|
|
974
1054
|
initial: Math.max(CLOUD_CHOICES.indexOf(scanned?.cloud || 'none'), 0)
|
|
975
1055
|
}
|
|
@@ -977,12 +1057,12 @@ async function main() {
|
|
|
977
1057
|
|
|
978
1058
|
const { package_manager, test_framework, max_file_lines } = await askQuestions([
|
|
979
1059
|
{
|
|
980
|
-
type: assumeYes ? null : 'select', name: 'package_manager', message: 'Package Manager:',
|
|
1060
|
+
type: assumeYes || !reviewScannedFields ? null : 'select', name: 'package_manager', message: 'Package Manager:',
|
|
981
1061
|
choices: PACKAGE_MANAGER_CHOICES.map(p => ({ title: p, value: p })),
|
|
982
1062
|
initial: Math.max(PACKAGE_MANAGER_CHOICES.indexOf(scanned?.package_manager || 'auto-detect'), 0)
|
|
983
1063
|
},
|
|
984
|
-
{ type: assumeYes ? null : 'text', name: 'test_framework', message: 'Test Framework (jest, phpunit, etc):', initial: scanned?.test_framework || 'auto-detect' },
|
|
985
|
-
{ type: assumeYes ? null : 'text', name: 'max_file_lines', message: 'Max lines per file:', initial: scanned?.max_file_lines || '300' }
|
|
1064
|
+
{ type: assumeYes || !reviewScannedFields ? null : 'text', name: 'test_framework', message: 'Test Framework (jest, phpunit, etc):', initial: scanned?.test_framework || 'auto-detect' },
|
|
1065
|
+
{ type: assumeYes || !reviewScannedFields ? null : 'text', name: 'max_file_lines', message: 'Max lines per file:', initial: scanned?.max_file_lines || '300' }
|
|
986
1066
|
]);
|
|
987
1067
|
|
|
988
1068
|
// Combine data
|
|
@@ -1037,9 +1117,26 @@ async function main() {
|
|
|
1037
1117
|
const claudeMdPath = path.join(targetDir, 'CLAUDE.md');
|
|
1038
1118
|
fs.writeFileSync(claudeMdPath, generateClaudeMd(data), 'utf8');
|
|
1039
1119
|
console.log(` ${pc.green('✓')} Generated ${pc.bold('CLAUDE.md')}`);
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1120
|
+
|
|
1121
|
+
if (!assumeYes) {
|
|
1122
|
+
const aiRefineAnswer = await askQuestions({
|
|
1123
|
+
type: 'confirm',
|
|
1124
|
+
name: 'ai_refine',
|
|
1125
|
+
message: 'Do you want an AI refinement prompt for PROJECT_CONTEXT.md?',
|
|
1126
|
+
initial: useScan
|
|
1127
|
+
});
|
|
1128
|
+
requestAiRefinement = Boolean(aiRefineAnswer.ai_refine);
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
let aiRefinementPath = null;
|
|
1132
|
+
if (requestAiRefinement) {
|
|
1133
|
+
aiRefinementPath = path.join(targetDir, 'AI_CONTEXT_REFINEMENT.md');
|
|
1134
|
+
fs.writeFileSync(aiRefinementPath, generateAiContextRefinementPrompt(data), 'utf8');
|
|
1135
|
+
console.log(` ${pc.green('✓')} Generated ${pc.bold('AI_CONTEXT_REFINEMENT.md')}`);
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
// Summary
|
|
1139
|
+
const autoSkills = resolveSkills(data);
|
|
1043
1140
|
console.log(`\n${pc.bold(pc.green('━━ Done! ━━'))}
|
|
1044
1141
|
|
|
1045
1142
|
${pc.bold('Project:')} ${data.project_name}
|
|
@@ -1052,11 +1149,12 @@ ${autoSkills.map(s => ' · ' + s).join('\n')}
|
|
|
1052
1149
|
${pc.bold('Generated files:')}
|
|
1053
1150
|
· ${pc.bold(projectContextPath)}
|
|
1054
1151
|
· ${pc.bold(claudeMdPath)}
|
|
1152
|
+
${aiRefinementPath ? ` · ${pc.bold(aiRefinementPath)}` : ''}
|
|
1055
1153
|
|
|
1056
1154
|
${pc.bold('Next steps:')}
|
|
1057
1155
|
1. Your kit is installed in ${pc.bold('./.agent')}
|
|
1058
1156
|
2. Review ${pc.bold('PROJECT_CONTEXT.md')} first and add architecture notes
|
|
1059
|
-
3. Instruct the agent to read/update ${pc.bold('PROJECT_CONTEXT.md')} before major tasks
|
|
1157
|
+
3. ${aiRefinementPath ? `Open ${pc.bold('AI_CONTEXT_REFINEMENT.md')} in your AI editor to refine project context` : `Instruct the agent to read/update ${pc.bold('PROJECT_CONTEXT.md')} before major tasks`}
|
|
1060
1158
|
4. Open project in Antigravity or Claude Code — the agent will read context on start
|
|
1061
1159
|
`);
|
|
1062
1160
|
}
|
package/package.json
CHANGED
package/scripts/init.py
CHANGED
|
@@ -607,7 +607,7 @@ Based on your stack, these skills will be loaded automatically:
|
|
|
607
607
|
{data.get('known_issues', '<!-- Add known issues or pending tasks -->')}
|
|
608
608
|
"""
|
|
609
609
|
|
|
610
|
-
def generate_claude_md(data):
|
|
610
|
+
def generate_claude_md(data):
|
|
611
611
|
"""Generate CLAUDE.md for Claude Code / Codex compatibility."""
|
|
612
612
|
return f"""# CLAUDE.md — {data['project_name']}
|
|
613
613
|
# Generated by thachvd-kit. See PROJECT_CONTEXT.md for full stack info.
|
|
@@ -636,8 +636,69 @@ Stack: {data['primary_language']} | {', '.join(data.get('frameworks', []))}
|
|
|
636
636
|
- `/test` — Run test suite
|
|
637
637
|
- `/deploy` — Deploy checklist
|
|
638
638
|
|
|
639
|
-
See PROJECT_CONTEXT.md for full agent routing table.
|
|
640
|
-
"""
|
|
639
|
+
See PROJECT_CONTEXT.md for full agent routing table.
|
|
640
|
+
"""
|
|
641
|
+
|
|
642
|
+
def generate_ai_context_refinement_prompt(data):
|
|
643
|
+
scan_evidence = data.get("scan_evidence", [])
|
|
644
|
+
evidence_block = "\n".join("- " + line for line in scan_evidence) if scan_evidence else "- No scan evidence was captured during init."
|
|
645
|
+
return f"""# AI Context Refinement
|
|
646
|
+
|
|
647
|
+
Use this prompt in your AI editor after `thachvd-kit init`.
|
|
648
|
+
|
|
649
|
+
## Goal
|
|
650
|
+
|
|
651
|
+
Refine `PROJECT_CONTEXT.md` so it reflects the real project more accurately than the baseline init scan.
|
|
652
|
+
|
|
653
|
+
## Current Baseline
|
|
654
|
+
|
|
655
|
+
- Project: {data['project_name']}
|
|
656
|
+
- Type: {data['project_type']}
|
|
657
|
+
- Stack: {data['primary_language']} | {', '.join(data.get('frameworks', [])) or 'no framework'}
|
|
658
|
+
- Database: {data.get('database', 'none')}
|
|
659
|
+
- Infra: {', '.join(data.get('infrastructure', [])) or 'none'}
|
|
660
|
+
|
|
661
|
+
## Scan Evidence
|
|
662
|
+
|
|
663
|
+
{evidence_block}
|
|
664
|
+
|
|
665
|
+
## Instructions For The AI Agent
|
|
666
|
+
|
|
667
|
+
1. Read `PROJECT_CONTEXT.md` first.
|
|
668
|
+
2. Inspect the project selectively to improve factual accuracy.
|
|
669
|
+
3. Prioritize:
|
|
670
|
+
- real database/config detection
|
|
671
|
+
- domain/capability inference
|
|
672
|
+
- architecture notes
|
|
673
|
+
- more accurate auto-resolved skills
|
|
674
|
+
- important project-specific constraints
|
|
675
|
+
4. Update `PROJECT_CONTEXT.md` directly.
|
|
676
|
+
5. Distinguish facts from inferences when uncertain.
|
|
677
|
+
6. Do not implement product code in this pass. Only refine project context.
|
|
678
|
+
|
|
679
|
+
## Suggested Files To Inspect
|
|
680
|
+
|
|
681
|
+
- Root manifests: `package.json`, `composer.json`, `Cargo.toml`, `pyproject.toml`
|
|
682
|
+
- Infrastructure/config: Docker, CI, env, framework config files
|
|
683
|
+
- Database config and models
|
|
684
|
+
- Main app entry points, routing, controllers/services
|
|
685
|
+
- README and existing documentation
|
|
686
|
+
|
|
687
|
+
## Desired Improvements
|
|
688
|
+
|
|
689
|
+
- Correct the `database` field if config files reveal the real DB.
|
|
690
|
+
- Add architecture notes that explain the actual structure.
|
|
691
|
+
- Infer domain capabilities such as scraping, browser automation, external API integrations, queues, workers, etc.
|
|
692
|
+
- Expand auto-resolved skills when there is clear evidence in the codebase.
|
|
693
|
+
- Add caveats or assumptions if parts of the stack are still uncertain.
|
|
694
|
+
|
|
695
|
+
## Completion Standard
|
|
696
|
+
|
|
697
|
+
When done, summarize:
|
|
698
|
+
- what was corrected
|
|
699
|
+
- what is still inferred
|
|
700
|
+
- which files provided the strongest evidence
|
|
701
|
+
"""
|
|
641
702
|
|
|
642
703
|
# ─── Main wizard ─────────────────────────────────────────────────────────────
|
|
643
704
|
|
|
@@ -675,6 +736,7 @@ def main():
|
|
|
675
736
|
use_scan = existing_mode == "scan"
|
|
676
737
|
|
|
677
738
|
scanned = scan_project() if use_scan else None
|
|
739
|
+
review_scanned_fields = not use_scan
|
|
678
740
|
if use_scan:
|
|
679
741
|
print(f" {dim('Scan mode: detecting stack from current project files...')}")
|
|
680
742
|
print(f" {bold('Scan result:')} {scanned['primary_language']} | {', '.join(scanned['frameworks']) or 'no framework'}")
|
|
@@ -684,6 +746,10 @@ def main():
|
|
|
684
746
|
for line in scanned["scan_evidence"]:
|
|
685
747
|
print(f" · {line}")
|
|
686
748
|
print()
|
|
749
|
+
if not args.yes:
|
|
750
|
+
scan_action = ask_select("Use detected context as-is or review fields manually",
|
|
751
|
+
["accept", "review"], default="accept")
|
|
752
|
+
review_scanned_fields = scan_action == "review"
|
|
687
753
|
elif not args.yes:
|
|
688
754
|
print(f" {dim('Manual mode: asking for project context explicitly.')}\n")
|
|
689
755
|
|
|
@@ -692,7 +758,7 @@ def main():
|
|
|
692
758
|
else:
|
|
693
759
|
data = {}
|
|
694
760
|
|
|
695
|
-
if not args.yes:
|
|
761
|
+
if not args.yes and review_scanned_fields:
|
|
696
762
|
# ── Project Info ──────────────────────────────────────────────────────
|
|
697
763
|
section("Project Info")
|
|
698
764
|
data["project_name"] = ask("Project name", default=(scanned or {}).get("project_name", Path.cwd().name))
|
|
@@ -783,11 +849,17 @@ def main():
|
|
|
783
849
|
# CLAUDE.md (for Claude Code / Codex)
|
|
784
850
|
if args.platform in ("claude", "all"):
|
|
785
851
|
claude_path = Path("CLAUDE.md")
|
|
786
|
-
claude_path.write_text(generate_claude_md(data), encoding="utf-8")
|
|
787
|
-
print(f" {green('✓')} {bold('CLAUDE.md')} generated (Claude Code / Codex)")
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
852
|
+
claude_path.write_text(generate_claude_md(data), encoding="utf-8")
|
|
853
|
+
print(f" {green('✓')} {bold('CLAUDE.md')} generated (Claude Code / Codex)")
|
|
854
|
+
|
|
855
|
+
ai_refine_path = None
|
|
856
|
+
if not args.yes and ask_bool("Generate AI context refinement prompt?", default=use_scan):
|
|
857
|
+
ai_refine_path = Path("AI_CONTEXT_REFINEMENT.md")
|
|
858
|
+
ai_refine_path.write_text(generate_ai_context_refinement_prompt(data), encoding="utf-8")
|
|
859
|
+
print(f" {green('✓')} {bold('AI_CONTEXT_REFINEMENT.md')} generated")
|
|
860
|
+
|
|
861
|
+
# Summary
|
|
862
|
+
auto_skills = resolve_skills(data)
|
|
791
863
|
print(f"""
|
|
792
864
|
{bold(green('━━ Done! ━━'))}
|
|
793
865
|
|
|
@@ -801,10 +873,11 @@ def main():
|
|
|
801
873
|
{bold('Generated files:')}
|
|
802
874
|
· {bold(str(output_path.resolve()))}
|
|
803
875
|
· {bold(str(Path("CLAUDE.md").resolve())) if args.platform in ("claude", "all") else 'CLAUDE.md not generated for this platform'}
|
|
876
|
+
· {bold(str(ai_refine_path.resolve())) if ai_refine_path else 'AI_CONTEXT_REFINEMENT.md not generated'}
|
|
804
877
|
|
|
805
878
|
{bold('Next steps:')}
|
|
806
879
|
1. Review {bold('PROJECT_CONTEXT.md')} first and add architecture notes
|
|
807
|
-
2. Instruct the agent to read/update
|
|
880
|
+
2. {"Open " + bold("AI_CONTEXT_REFINEMENT.md") + " in your AI editor to refine project context" if ai_refine_path else "Instruct the agent to read/update " + bold("PROJECT_CONTEXT.md") + " before major tasks"}
|
|
808
881
|
3. Open project in your AI editor (Antigravity / Claude Code / Codex)
|
|
809
882
|
4. The agent will read PROJECT_CONTEXT.md on session start
|
|
810
883
|
|