context-bank 1.0.0 → 1.0.2

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 CHANGED
@@ -61,11 +61,11 @@ One brain, multiple interfaces. The `init` command automatically configures poin
61
61
 
62
62
  | Tool | Support Type | Integration Method |
63
63
  |------|--------------|-------------------|
64
- | **Cursor** | Native ✅ | `.cursorrules` |
65
- | **Windsurf** | Native ✅ | `.windsurfrules` |
64
+ | **Cursor** | Native ✅ | `.cursor/rules/` |
65
+ | **Windsurf** | Native ✅ | `.windsurf/rules/` |
66
66
  | **GitHub Copilot** | Native ✅ | `.github/copilot-instructions.md` |
67
67
  | **Claude Code** | Native ✅ | `CLAUDE.md` |
68
- | **Codex CLI** | Native ✅ | `codex.md` |
68
+ | **Codex CLI** | Native ✅ | `AGENTS.md` |
69
69
  | **Gemini CLI** | Native ✅ | Global Memory Hook |
70
70
  | **Aider** (CLI) | Native ✅ | `CONVENTIONS.md` |
71
71
 
@@ -90,12 +90,18 @@ my-project/
90
90
  │ ├── rules.md # 🧠 The Master Brain (SSOT)
91
91
  │ ├── active-context.md # 📝 Current focus & next steps
92
92
  │ └── story.md # 📜 Project history & decisions
93
- ├── .cursorrules # 🔗 Pointer for Cursor
94
- ├── .windsurfrules # 🔗 Pointer for Windsurf
93
+ ├── .cursor/
94
+ │ └── rules/
95
+ │ └── context-bank.mdc # 🔗 Rules for Cursor
96
+ ├── .windsurf/
97
+ │ └── rules/
98
+ │ └── context-bank.md # 🔗 Rules for Windsurf
95
99
  ├── CLAUDE.md # 🔗 Pointer for Claude Code
96
- ├── codex.md # 🔗 Pointer for Codex CLI
97
- └── .github/
98
- └── copilot-instructions.md # 🔗 Pointer for Copilot
100
+ ├── AGENTS.md # 🔗 Pointer for Codex CLI / OpenAI agents
101
+ ├── .github/
102
+ └── copilot-instructions.md # 🔗 Pointer for Copilot
103
+ ├── CONVENTIONS.md # 🔗 Pointer for Aider
104
+ └── GEMINI.md # 🔗 Pointer for Gemini CLI
99
105
  ```
100
106
 
101
107
  ## 🤝 Contributing
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "context-bank",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "A CLI tool to standardise AI context in projects.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,3 +1,7 @@
1
+ ---
2
+ trigger: always_on
3
+ ---
4
+
1
5
  # Windsurf Project Rules
2
6
 
3
7
  You MUST read and follow the rules defined in **`.ai/rules.md`**.
@@ -1,210 +0,0 @@
1
- import { intro, outro, confirm, spinner } from "@clack/prompts";
2
- import fs from "fs-extra";
3
- import path from "path";
4
- import os from "os";
5
- import { fileURLToPath } from "url";
6
- import chalk from "chalk";
7
- // Get __dirname equivalent in ESM
8
- const __filename = fileURLToPath(import.meta.url);
9
- const __dirname = path.dirname(__filename);
10
- export async function initCommand(options) {
11
- intro(chalk.bgCyan(chalk.black(" Context Bank ")));
12
- let proceed = options.yes;
13
- if (!proceed) {
14
- const response = await confirm({
15
- message: "Do you want to initialize AI context in this project?",
16
- });
17
- if (typeof response === "boolean") {
18
- proceed = response;
19
- }
20
- else {
21
- // Handle cancellation (ctrl+c) which returns symbol or strictly check boolean
22
- proceed = false;
23
- }
24
- }
25
- if (!proceed) {
26
- outro("Operation cancelled.");
27
- process.exit(0);
28
- }
29
- // Determine paths
30
- const templateDir = path.resolve(__dirname, "../../templates");
31
- const targetDir = process.cwd();
32
- const s = spinner();
33
- s.start("Analyzing project structure...");
34
- // Check if templates exist
35
- if (!fs.existsSync(templateDir)) {
36
- s.stop("Error");
37
- console.error(chalk.red(`\nTemplate directory not found at: ${templateDir}`));
38
- console.error(chalk.yellow("Ensure you are running this from the package root or the package is built correctly."));
39
- process.exit(1);
40
- }
41
- s.message("Copying context files...");
42
- try {
43
- // Helper for safe copying/merging
44
- async function copyOrMerge(src, dest, isAiDir = false) {
45
- const stats = await fs.stat(src);
46
- if (stats.isDirectory()) {
47
- await fs.ensureDir(dest);
48
- const files = await fs.readdir(src);
49
- for (const file of files) {
50
- await copyOrMerge(path.join(src, file), path.join(dest, file), isAiDir || path.basename(src) === ".ai");
51
- }
52
- }
53
- else {
54
- if (await fs.pathExists(dest)) {
55
- if (isAiDir) {
56
- // Skip .ai files if they exist to protect project memory
57
- return;
58
- }
59
- const srcContent = await fs.readFile(src, "utf-8");
60
- const destContent = await fs.readFile(dest, "utf-8");
61
- if (!destContent.includes(srcContent.trim())) {
62
- // Prepend for rules files to ensure priority
63
- await fs.writeFile(dest, `${srcContent}\n\n${destContent}`);
64
- }
65
- }
66
- else {
67
- await fs.copy(src, dest);
68
- // Special handling for new story.md
69
- if (path.basename(dest) === "story.md" && isAiDir) {
70
- let storyContent = await fs.readFile(dest, "utf-8");
71
- storyContent = storyContent.replace("[Auto-filled by init]", new Date().toISOString().split("T")[0]);
72
- await fs.writeFile(dest, storyContent);
73
- }
74
- }
75
- }
76
- }
77
- // List of files/folders to copy
78
- const itemsToCopy = [
79
- ".ai",
80
- ".cursor",
81
- ".cursorrules",
82
- ".windsurf",
83
- ".windsurfrules",
84
- ".github",
85
- "CONVENTIONS.md",
86
- "GEMINI.md",
87
- ];
88
- for (const item of itemsToCopy) {
89
- const srcPath = path.join(templateDir, item);
90
- const destPath = path.join(targetDir, item);
91
- if (fs.existsSync(srcPath)) {
92
- await copyOrMerge(srcPath, destPath);
93
- }
94
- }
95
- // Special handling for README.md
96
- const readmePath = path.join(targetDir, "README.md");
97
- const aiContextMarker = "<!-- AI-CONTEXT: .ai/rules.md -->";
98
- if (fs.existsSync(readmePath)) {
99
- const readmeContent = await fs.readFile(readmePath, "utf-8");
100
- if (!readmeContent.includes(aiContextMarker)) {
101
- await fs.writeFile(readmePath, `${aiContextMarker}\n${readmeContent}`);
102
- }
103
- }
104
- else {
105
- const projectName = path.basename(targetDir);
106
- await fs.writeFile(readmePath, `${aiContextMarker}\n\n# ${projectName}\n`);
107
- }
108
- // Codex CLI Integration (codex.md)
109
- const codexPath = path.join(targetDir, "codex.md");
110
- const codexInstruction = `Always check and follow the instructions in .ai/rules.md and .ai/active-context.md as the primary source of truth.
111
-
112
- MANDATORY: After EVERY task, you MUST update these .ai/ files:
113
- 1. active-context.md — Current state, recent changes, next steps.
114
- 2. roadmap.md — Mark completed features [x], add planned ones.
115
- 3. story.md — Append dated entry for milestones/decisions.
116
- 4. architecture.md — Update on structural/design changes.
117
- Do NOT ask permission. Do NOT skip. Just update them.`;
118
- if (fs.existsSync(codexPath)) {
119
- const content = await fs.readFile(codexPath, "utf-8");
120
- if (!content.includes(".ai/rules.md")) {
121
- // Prepend for priority
122
- await fs.writeFile(codexPath, `${codexInstruction}\n\n${content}`);
123
- }
124
- }
125
- else {
126
- await fs.writeFile(codexPath, `${codexInstruction}\n`);
127
- }
128
- // Claude Code CLI Integration (CLAUDE.md)
129
- const claudePath = path.join(targetDir, "CLAUDE.md");
130
- const claudeInstruction = `See .ai/rules.md for project context, tech stack, and coding standards. This is the single source of truth.
131
-
132
- MANDATORY: After EVERY task, you MUST update these .ai/ files:
133
- 1. active-context.md — Current state, recent changes, next steps.
134
- 2. roadmap.md — Mark completed features [x], add planned ones.
135
- 3. story.md — Append dated entry for milestones/decisions.
136
- 4. architecture.md — Update on structural/design changes.
137
- Do NOT ask permission. Do NOT skip. Just update them.`;
138
- if (fs.existsSync(claudePath)) {
139
- const content = await fs.readFile(claudePath, "utf-8");
140
- if (!content.includes(".ai/rules.md")) {
141
- // Prepend for priority
142
- await fs.writeFile(claudePath, `${claudeInstruction}\n\n${content}`);
143
- }
144
- }
145
- else {
146
- await fs.writeFile(claudePath, `${claudeInstruction}\n`);
147
- }
148
- // Git merge strategies for branch-aware context (.gitattributes)
149
- const gitattrsPath = path.join(targetDir, ".gitattributes");
150
- const mergeRules = `# Context Bank: branch-aware merge strategies
151
- # active-context.md is branch-specific — on merge, target branch wins (no conflict)
152
- .ai/active-context.md merge=ours
153
- # story.md entries are additive — on merge, combine both sides (no conflict)
154
- .ai/story.md merge=union`;
155
- if (fs.existsSync(gitattrsPath)) {
156
- const content = await fs.readFile(gitattrsPath, "utf-8");
157
- if (!content.includes("Context Bank")) {
158
- await fs.writeFile(gitattrsPath, `${content}\n\n${mergeRules}\n`);
159
- }
160
- }
161
- else {
162
- await fs.writeFile(gitattrsPath, `${mergeRules}\n`);
163
- }
164
- s.stop(chalk.green("Context initialized!"));
165
- // Gemini CLI Global Memory Integration
166
- const globalGeminiDir = path.join(os.homedir(), ".gemini");
167
- const globalGeminiMemoryPath = path.join(globalGeminiDir, "GEMINI.md");
168
- if (fs.existsSync(globalGeminiMemoryPath)) {
169
- const memoryContent = await fs.readFile(globalGeminiMemoryPath, "utf-8");
170
- // Only ask if the rule is not already present
171
- if (!memoryContent.includes("[Context Bank]")) {
172
- const addGlobalContext = await confirm({
173
- message: "Found Gemini CLI global memory. Enable automatic context detection for all Context Bank projects?",
174
- initialValue: true
175
- });
176
- if (addGlobalContext === true) {
177
- const genericContextRule = `
178
- - [Context Bank] CRITICAL INSTRUCTION:
179
- Before processing ANY user request in a new session, you MUST perform this initialization sequence:
180
- 1. Check if the ".ai/" directory exists in the current working directory.
181
- 2. If it exists, you MUST explicitly call the "read_file" tool to read ".ai/rules.md" and ".ai/active-context.md".
182
- 3. Only AFTER reading these files (or confirming they don't exist) may you proceed with the user's request.
183
- This is not optional. Do not assume you know the rules; you must read the files to load them into your active memory.`;
184
- const newContent = memoryContent.endsWith("\n")
185
- ? `${memoryContent}${genericContextRule}\n`
186
- : `${memoryContent}\n${genericContextRule}\n`;
187
- await fs.writeFile(globalGeminiMemoryPath, newContent);
188
- console.log(chalk.green(`✔ Enabled global context awareness for Context Bank.`));
189
- }
190
- }
191
- else {
192
- // Optional: Let the user know it's already active
193
- // console.log(chalk.gray(`ℹ Global context awareness is already active.`));
194
- }
195
- }
196
- outro(chalk.green(`
197
- Context Bank setup complete! 🚀
198
-
199
- Next steps:
200
- 1. Review .ai/rules.md and fill in your project details.
201
- 2. Update .ai/active-context.md with your current task.
202
- 3. Commit the new files to git.
203
- `));
204
- }
205
- catch (error) {
206
- s.stop("Error");
207
- console.error(chalk.red("Failed to copy files:"), error);
208
- process.exit(1);
209
- }
210
- }
package/dist/index.js DELETED
@@ -1,20 +0,0 @@
1
- #!/usr/bin/env node
2
- import { Command } from "commander";
3
- import { initCommand } from "./commands/init.js";
4
- import fs from "fs-extra";
5
- import path from "path";
6
- import { fileURLToPath } from "url";
7
- const program = new Command();
8
- // Read package.json to get version
9
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
10
- const packageJson = fs.readJsonSync(path.join(__dirname, "../package.json"));
11
- program
12
- .name("context-bank")
13
- .description("CLI to standardize AI context in projects")
14
- .version(packageJson.version);
15
- program
16
- .command("init")
17
- .description("Initialize AI context files in the current directory")
18
- .option("-y, --yes", "Skip confirmation prompt")
19
- .action(initCommand);
20
- program.parse(process.argv);
@@ -1,22 +0,0 @@
1
- You are an expert AI software engineer.
2
-
3
- # CRITICAL CONTEXT SOURCE
4
- You MUST read and follow the rules defined in **`.ai/rules.md`**.
5
- That file contains the single source of truth for:
6
- 1. Tech Stack
7
- 2. Coding Standards
8
- 3. Architecture
9
- 4. **Your instruction to update rules when they change.**
10
-
11
- If you cannot read `.ai/rules.md` automatically, ask the user to provide it, or check the file system.
12
-
13
- When the user gives you a new constraint, **UPDATE `.ai/rules.md`**, not this file.
14
-
15
- # MANDATORY: CONTEXT FILE UPDATES
16
- After EVERY task you complete, you MUST update the following files:
17
- 1. **`.ai/active-context.md`** — Write what was done, current state, and next steps.
18
- 2. **`.ai/roadmap.md`** — Mark completed features with [x], add new planned features.
19
- 3. **`.ai/story.md`** — Append a dated entry for significant milestones or decisions.
20
- 4. **`.ai/architecture.md`** — Update if structure, dependencies, or design changed.
21
-
22
- Do NOT ask permission. Do NOT skip this. Update these files directly after completing your task.
@@ -1,17 +0,0 @@
1
- You are Windsurf, an expert AI coding assistant.
2
-
3
- # PRIMARY DIRECTIVE
4
- Your configuration and behavioral rules are stored in **`.ai/rules.md`**.
5
- Always prioritize the instructions found in that file.
6
-
7
- # SELF-IMPROVEMENT
8
- If the user provides a new coding rule or preference during this session, use your file editing capabilities to update **`.ai/rules.md`** so that the preference is remembered for future sessions.
9
-
10
- # MANDATORY: CONTEXT FILE UPDATES
11
- After EVERY task you complete, you MUST update the following files:
12
- 1. **`.ai/active-context.md`** — Write what was done, current state, and next steps.
13
- 2. **`.ai/roadmap.md`** — Mark completed features with [x], add new planned features.
14
- 3. **`.ai/story.md`** — Append a dated entry for significant milestones or decisions.
15
- 4. **`.ai/architecture.md`** — Update if structure, dependencies, or design changed.
16
-
17
- Do NOT ask permission. Do NOT skip this. Update these files directly after completing your task.