@esotech/contextuate 2.0.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.
Files changed (62) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +287 -0
  3. package/dist/commands/context.js +80 -0
  4. package/dist/commands/create.js +93 -0
  5. package/dist/commands/index.js +46 -0
  6. package/dist/commands/init.js +452 -0
  7. package/dist/commands/install.js +359 -0
  8. package/dist/commands/remove.js +77 -0
  9. package/dist/commands/run.js +205 -0
  10. package/dist/index.js +96 -0
  11. package/dist/runtime/driver.js +64 -0
  12. package/dist/runtime/tools.js +48 -0
  13. package/dist/templates/README.md +152 -0
  14. package/dist/templates/agents/aegis.md +366 -0
  15. package/dist/templates/agents/archon.md +247 -0
  16. package/dist/templates/agents/atlas.md +326 -0
  17. package/dist/templates/agents/canvas.md +19 -0
  18. package/dist/templates/agents/chronicle.md +424 -0
  19. package/dist/templates/agents/chronos.md +20 -0
  20. package/dist/templates/agents/cipher.md +360 -0
  21. package/dist/templates/agents/crucible.md +375 -0
  22. package/dist/templates/agents/echo.md +297 -0
  23. package/dist/templates/agents/forge.md +613 -0
  24. package/dist/templates/agents/ledger.md +317 -0
  25. package/dist/templates/agents/meridian.md +281 -0
  26. package/dist/templates/agents/nexus.md +600 -0
  27. package/dist/templates/agents/oracle.md +281 -0
  28. package/dist/templates/agents/scribe.md +612 -0
  29. package/dist/templates/agents/sentinel.md +312 -0
  30. package/dist/templates/agents/unity.md +17 -0
  31. package/dist/templates/agents/vox.md +19 -0
  32. package/dist/templates/agents/weaver.md +334 -0
  33. package/dist/templates/framework-agents/base.md +166 -0
  34. package/dist/templates/framework-agents/documentation-expert.md +292 -0
  35. package/dist/templates/framework-agents/tools-expert.md +245 -0
  36. package/dist/templates/standards/agent-roles.md +34 -0
  37. package/dist/templates/standards/agent-workflow.md +170 -0
  38. package/dist/templates/standards/behavioral-guidelines.md +145 -0
  39. package/dist/templates/standards/coding-standards.md +171 -0
  40. package/dist/templates/standards/task-workflow.md +246 -0
  41. package/dist/templates/templates/context.md +33 -0
  42. package/dist/templates/templates/contextuate.md +109 -0
  43. package/dist/templates/templates/platforms/AGENTS.md +5 -0
  44. package/dist/templates/templates/platforms/CLAUDE.md +5 -0
  45. package/dist/templates/templates/platforms/GEMINI.md +5 -0
  46. package/dist/templates/templates/platforms/clinerules.md +5 -0
  47. package/dist/templates/templates/platforms/copilot.md +5 -0
  48. package/dist/templates/templates/platforms/cursor.mdc +9 -0
  49. package/dist/templates/templates/platforms/windsurf.md +5 -0
  50. package/dist/templates/templates/standards/go.standards.md +167 -0
  51. package/dist/templates/templates/standards/java.standards.md +167 -0
  52. package/dist/templates/templates/standards/javascript.standards.md +292 -0
  53. package/dist/templates/templates/standards/php.standards.md +181 -0
  54. package/dist/templates/templates/standards/python.standards.md +175 -0
  55. package/dist/templates/tools/agent-creator.tool.md +252 -0
  56. package/dist/templates/tools/quickref.tool.md +216 -0
  57. package/dist/templates/tools/spawn.tool.md +31 -0
  58. package/dist/templates/tools/standards-detector.tool.md +301 -0
  59. package/dist/templates/version.json +8 -0
  60. package/dist/utils/git.js +62 -0
  61. package/dist/utils/tokens.js +74 -0
  62. package/package.json +59 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Alexander David Conroy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,287 @@
1
+ # Contextuate Framework
2
+
3
+ <p align="center">
4
+ <a href="https://contextuate.md">
5
+ <img src="assets/logo-black.png" alt="Contextuate Logo" width="200" />
6
+ </a>
7
+ </p>
8
+
9
+
10
+ **Standardized AI Context for Software Projects**
11
+
12
+ Contextuate provides a structured "brain" for your project that AI coding assistants (like Claude, Copilot, Cursor) can understand. It standardizes how AI agents receive context, follow coding standards, and execute tasks.
13
+
14
+ ## Quick Start
15
+
16
+ ### One-Line Install (Recommended)
17
+
18
+ ```bash
19
+ curl -fsSL https://contextuate.md/install.sh | sh
20
+ ```
21
+
22
+ ### Install via npm
23
+
24
+ ```bash
25
+ npm install -g @esotech/contextuate
26
+ ```
27
+
28
+ Or use directly with npx:
29
+
30
+ ```bash
31
+ npx @esotech/contextuate init
32
+ ```
33
+
34
+ ### Install from Source
35
+
36
+ Clone the repository and install globally:
37
+
38
+ ```bash
39
+ git clone https://github.com/esotech/contextuate.git
40
+ cd contextuate
41
+ npm install
42
+ npm run build
43
+ npm link
44
+ ```
45
+
46
+ ### Initialize Your Project
47
+
48
+ Navigate to your project directory and run:
49
+
50
+ ```bash
51
+ contextuate init
52
+ ```
53
+
54
+ The interactive installer will guide you through:
55
+ 1. Selecting which AI platforms to configure (Claude Code, Cursor, Copilot, Windsurf, etc.)
56
+ 2. Creating the `docs/ai/` directory structure with framework files
57
+ 3. Generating platform-specific configuration files
58
+ 4. Setting up symlinks for supported platforms (e.g., `.claude/` for Claude Code)
59
+
60
+ ## What is Contextuate?
61
+
62
+ Contextuate is a directory structure and set of conventions that helps AI agents work more effectively. It turns implicit project knowledge into explicit, structured context.
63
+
64
+ - **`docs/ai/.contextuate/contextuate.md`**: The framework bootstrap file. It links to everything else.
65
+ - **`docs/ai/context.md`**: Your project-specific context (Identity, Tech Stack).
66
+ - **`docs/ai/project-structure.md`**: Auto-generated file tree map (created by `contextuate index`).
67
+ - **`docs/ai/agents/`**: Specialized "personas" for your AI (e.g., `documentation-expert`).
68
+ - **`docs/ai/standards/`**: Explicit coding standards and behavioral guidelines.
69
+ - **`docs/ai/quickrefs/`**: Condensed documentation optimized for AI token limits.
70
+ - **`docs/ai/tasks/`**: A workflow for managing multi-session AI tasks.
71
+
72
+ ## How LLMs Use Contextuate
73
+
74
+ 1. **Discovery**: The AI reads `docs/ai/.contextuate/contextuate.md` first. This file maps the project and links to all other resources.
75
+ 2. **Specialization**: If acting as a specific agent, it reads `docs/ai/agents/<name>.md` to load specific capabilities and rules.
76
+ 3. **Execution**: The AI follows the linked standards in `docs/ai/standards/` and uses `docs/ai/quickrefs/` for technical lookups.
77
+ 4. **Memory**: If working on a long-running task, it tracks state in `docs/ai/tasks/<task-name>/` to maintain context across sessions.
78
+
79
+ When using the `contextuate run` command, this context loading is automated based on the agent definition.
80
+
81
+ ## Repository Structure
82
+
83
+ This repository contains the source for the Contextuate framework.
84
+
85
+ - **`docs/ai/.contextuate/`**: The core framework files distributed to users.
86
+ - `agents/`: Base agent definitions.
87
+ - `templates/`: Templates for new projects.
88
+ - `tools/`: AI tool guides.
89
+
90
+
91
+ ## Usage
92
+
93
+ Once installed, you customize the framework for your project:
94
+
95
+ 1. Edit **`docs/ai/context.md`** with your project details (Identity, Tech Stack).
96
+ * *Note: `docs/ai/.contextuate/contextuate.md` is the framework entry point and typically shouldn't be edited.*
97
+ 2. Create custom agents in **`docs/ai/agents/`** (using the Agent Creator tool).
98
+ 3. Document coding standards in **`docs/ai/standards/`**.
99
+ 4. Generate quickrefs in **`docs/ai/quickrefs/`**.
100
+
101
+ ## CLI Usage
102
+
103
+ ### Global Options
104
+
105
+ ```bash
106
+ contextuate --help # Display all available commands
107
+ contextuate --version # Display the installed version
108
+ contextuate -V # Short form for version
109
+ ```
110
+
111
+ ### Command Reference
112
+
113
+ | Command | Description |
114
+ | :------------- | :--------------------------------------- |
115
+ | `init` | Initialize Contextuate in a project |
116
+ | `install` | Install templates (agents, standards) |
117
+ | `run` | Execute an agent |
118
+ | `create-agent` | Create a new agent definition |
119
+ | `index` | Generate a project file tree |
120
+ | `add-context` | Interactively add files to context |
121
+ | `remove` | Clean up framework files |
122
+
123
+ ---
124
+
125
+ ### `contextuate init`
126
+
127
+ Initialize Contextuate in the current project.
128
+
129
+ ```bash
130
+ # Interactive mode - prompts for platforms and agents
131
+ contextuate init
132
+
133
+ # Non-interactive - specify platforms directly
134
+ contextuate init claude cursor copilot
135
+ contextuate init all # Install all platforms
136
+
137
+ # With agents
138
+ contextuate init claude --agents archon base
139
+ contextuate init claude --agents all
140
+
141
+ # Force overwrite existing files
142
+ contextuate init claude --force
143
+ ```
144
+
145
+ **Options:**
146
+ - `-f, --force` - Overwrite existing files
147
+ - `-a, --agents <names...>` - Install specific agents (e.g., "base archon" or "all")
148
+
149
+ **Available Platforms:** `agents`, `antigravity`, `claude`, `cline`, `cursor`, `gemini`, `copilot`, `windsurf`
150
+
151
+ ---
152
+
153
+ ### `contextuate install`
154
+
155
+ Install templates from the global Contextuate repository. Supports both flag-style and subcommand-style usage.
156
+
157
+ ```bash
158
+ # Interactive mode
159
+ contextuate install
160
+
161
+ # List available templates
162
+ contextuate install --list
163
+
164
+ # Install all templates
165
+ contextuate install --all
166
+
167
+ # Flag style - install specific items
168
+ contextuate install --agents archon base canvas
169
+ contextuate install --standards php javascript
170
+ contextuate install --tools quickref
171
+
172
+ # Subcommand style
173
+ contextuate install agents archon base
174
+ contextuate install agents --all
175
+ contextuate install standards php javascript python
176
+ contextuate install standards --all
177
+ contextuate install tools --all
178
+
179
+ # Force overwrite
180
+ contextuate install agents --all --force
181
+ ```
182
+
183
+ **Options:**
184
+ - `-a, --agents <names...>` - Install specific agents
185
+ - `-s, --standards <names...>` - Install language standards
186
+ - `-t, --tools <names...>` - Install tools
187
+ - `--all` - Install all available templates
188
+ - `-l, --list` - List available templates
189
+ - `-f, --force` - Overwrite existing files
190
+
191
+ **Subcommands:**
192
+ - `install agents [names...]` - Install agent templates
193
+ - `install standards [names...]` - Install language standard templates
194
+ - `install tools [names...]` - Install tool templates
195
+
196
+ ---
197
+
198
+ ### `contextuate run`
199
+
200
+ Execute an agent definition with optional task context.
201
+
202
+ ```bash
203
+ contextuate run documentation-expert
204
+ contextuate run archon --goal "Review the codebase structure"
205
+ contextuate run forge --task my-feature
206
+ contextuate run nexus --dry-run
207
+ ```
208
+
209
+ **Options:**
210
+ - `--dry-run` - Simulate execution without running logic
211
+ - `--isolation <mode>` - Isolation mode (`worktree`, `none`). Default: `none`
212
+ - `--goal <text>` - Goal or instructions for the agent
213
+ - `--task <name>` - Load a task context (scope and latest log)
214
+
215
+ ---
216
+
217
+ ### `contextuate create-agent`
218
+
219
+ Create a new agent definition.
220
+
221
+ ```bash
222
+ # Interactive mode
223
+ contextuate create-agent
224
+
225
+ # With name
226
+ contextuate create-agent my-custom-agent
227
+ contextuate new-agent my-custom-agent # Alias
228
+
229
+ # With description
230
+ contextuate create-agent api-expert --description "Expert in REST API design"
231
+ ```
232
+
233
+ **Options:**
234
+ - `-d, --description <text>` - Description of the agent
235
+
236
+ ---
237
+
238
+ ### `contextuate index`
239
+
240
+ Generate a project structure index for AI context.
241
+
242
+ ```bash
243
+ contextuate index
244
+ contextuate index --depth 3
245
+ contextuate index --force
246
+ ```
247
+
248
+ **Options:**
249
+ - `-d, --depth <number>` - Maximum depth of the file tree. Default: `5`
250
+ - `-f, --force` - Overwrite existing index
251
+
252
+ ---
253
+
254
+ ### `contextuate add-context`
255
+
256
+ Interactively add files to `docs/ai/context.md`.
257
+
258
+ ```bash
259
+ contextuate add-context
260
+ ```
261
+
262
+ ---
263
+
264
+ ### `contextuate remove`
265
+
266
+ Remove unmodified platform jump files.
267
+
268
+ ```bash
269
+ contextuate remove
270
+ ```
271
+
272
+ ## Documentation
273
+
274
+ For full documentation, see [contextuate.md](https://contextuate.md) or browse the `docs/ai/.contextuate/` directory.
275
+
276
+ ## Changelog
277
+
278
+ See [CHANGELOG.md](CHANGELOG.md) for version history and release notes.
279
+
280
+ ## License
281
+
282
+ [MIT License](LICENSE)
283
+
284
+ ## Credits
285
+
286
+ Powered by **Esotech**.
287
+ Created by **Alexander Conroy** ([@geilt](https://github.com/geilt)).
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.addContextCommand = addContextCommand;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const fs_extra_1 = __importDefault(require("fs-extra"));
9
+ const path_1 = __importDefault(require("path"));
10
+ const inquirer_1 = __importDefault(require("inquirer"));
11
+ const tokens_1 = require("../utils/tokens");
12
+ async function addContextCommand() {
13
+ console.log(chalk_1.default.blue('[INFO] Interactive Context Creator'));
14
+ const contextFile = path_1.default.join(process.cwd(), 'docs/ai/context.md');
15
+ if (!await fs_extra_1.default.pathExists(contextFile)) {
16
+ console.error(chalk_1.default.red(`[ERROR] context.md not found at ${contextFile}`));
17
+ console.log(chalk_1.default.yellow('Run "contextuate init" first.'));
18
+ return;
19
+ }
20
+ // 1. Scan for files
21
+ // In a real app we'd need a more robust file picker or fuzzy search
22
+ // For now we will just list files in root and src (depth 2) to pick from
23
+ // or allow typing a path.
24
+ const { action } = await inquirer_1.default.prompt([
25
+ {
26
+ type: 'list',
27
+ name: 'action',
28
+ message: 'What would you like to do?',
29
+ choices: [
30
+ { name: 'Add specific file by path', value: 'path' },
31
+ // { name: 'Select from list (root)', value: 'select' }, // Hard to implement well without a huge list
32
+ { name: 'Cancel', value: 'cancel' }
33
+ ]
34
+ }
35
+ ]);
36
+ if (action === 'cancel')
37
+ return;
38
+ if (action === 'path') {
39
+ const { filePath } = await inquirer_1.default.prompt([
40
+ {
41
+ type: 'input',
42
+ name: 'filePath',
43
+ message: 'Enter relative path to file (e.g. src/index.ts):',
44
+ validate: async (input) => {
45
+ if (!await fs_extra_1.default.pathExists(path_1.default.join(process.cwd(), input))) {
46
+ return 'File does not exist';
47
+ }
48
+ return true;
49
+ }
50
+ }
51
+ ]);
52
+ await appendToContext(contextFile, filePath);
53
+ }
54
+ }
55
+ async function appendToContext(contextFile, targetFile) {
56
+ const content = await fs_extra_1.default.readFile(targetFile, 'utf-8');
57
+ const tokens = (0, tokens_1.estimateTokens)(content);
58
+ console.log(`Analyzing ${targetFile}... (~${tokens} tokens)`);
59
+ // Check if valid to add
60
+ if (tokens > 5000) {
61
+ const { confirm } = await inquirer_1.default.prompt([
62
+ {
63
+ type: 'confirm',
64
+ name: 'confirm',
65
+ message: `This file is large (~${tokens} tokens). Are you sure you want to add it?`,
66
+ default: false
67
+ }
68
+ ]);
69
+ if (!confirm)
70
+ return;
71
+ }
72
+ const docEntry = `
73
+ ## [File: ${targetFile}](file:///${path_1.default.resolve(targetFile)})
74
+ \`\`\`${path_1.default.extname(targetFile).substring(1) || 'text'}
75
+ ${content}
76
+ \`\`\`
77
+ `;
78
+ await fs_extra_1.default.appendFile(contextFile, docEntry);
79
+ console.log(chalk_1.default.green(`[OK] Added ${targetFile} to context.md`));
80
+ }
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createAgentCommand = createAgentCommand;
7
+ const inquirer_1 = __importDefault(require("inquirer"));
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const fs_extra_1 = __importDefault(require("fs-extra"));
10
+ const path_1 = __importDefault(require("path"));
11
+ async function createAgentCommand(name, options) {
12
+ console.log(chalk_1.default.blue('╔════════════════════════════════════════╗'));
13
+ console.log(chalk_1.default.blue('║ Contextuate Agent Creator ║'));
14
+ console.log(chalk_1.default.blue('╚════════════════════════════════════════╝'));
15
+ console.log('');
16
+ let agentName = name;
17
+ let agentDescription = options.description;
18
+ // Prompt for name if not provided
19
+ if (!agentName) {
20
+ const answers = await inquirer_1.default.prompt([
21
+ {
22
+ type: 'input',
23
+ name: 'name',
24
+ message: 'What is the name of the new agent? (kebab-case)',
25
+ validate: (input) => /^[a-z0-9-]+$/.test(input) || 'Name must be lowercase alphanumeric with hyphens',
26
+ },
27
+ ]);
28
+ agentName = answers.name;
29
+ }
30
+ // Prompt for description if not provided
31
+ if (!agentDescription) {
32
+ const answers = await inquirer_1.default.prompt([
33
+ {
34
+ type: 'input',
35
+ name: 'description',
36
+ message: 'Briefly describe what this agent does:',
37
+ default: 'A specialized agent for...',
38
+ },
39
+ ]);
40
+ agentDescription = answers.description;
41
+ }
42
+ const agentsDir = path_1.default.join(process.cwd(), 'docs/ai/agents');
43
+ const agentFile = path_1.default.join(agentsDir, `${agentName}.md`);
44
+ await fs_extra_1.default.ensureDir(agentsDir);
45
+ if (await fs_extra_1.default.pathExists(agentFile)) {
46
+ console.error(chalk_1.default.red(`[ERROR] Agent already exists: ${agentFile}`));
47
+ // Optional: Ask to overwrite
48
+ process.exit(1);
49
+ }
50
+ const template = `---
51
+ name: "${agentName}"
52
+ description: "${agentDescription}"
53
+ version: "1.0.0"
54
+ capabilities:
55
+ - "read_files"
56
+ - "search_files"
57
+ context:
58
+ files:
59
+ - "docs/context.md"
60
+ directories:
61
+ - "src/"
62
+ env: []
63
+ ---
64
+
65
+ # ${agentName.split('-').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ')}
66
+
67
+ > **Purpose:** ${agentDescription}
68
+ > **Inherits:** [Base Agent](../.contextuate/agents/base.md)
69
+
70
+ ## Role
71
+
72
+ Describe the specific role and improvements this agent provides.
73
+
74
+ ## Specialized Rules
75
+
76
+ 1. **Rule 1**: Description
77
+ 2. **Rule 2**: Description
78
+
79
+ ---
80
+ `;
81
+ try {
82
+ await fs_extra_1.default.writeFile(agentFile, template);
83
+ console.log(chalk_1.default.green(`[OK] Created agent: ${agentFile}`));
84
+ console.log('');
85
+ console.log('Next steps:');
86
+ console.log(`1. Edit ${chalk_1.default.cyan(agentFile)} to refine rules and context.`);
87
+ console.log(`2. Run it with: ${chalk_1.default.yellow(`contextuate run ${agentName}`)}`);
88
+ }
89
+ catch (error) {
90
+ console.error(chalk_1.default.red('[ERROR] Failed to write agent file:'), error);
91
+ process.exit(1);
92
+ }
93
+ }
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.indexCommand = indexCommand;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const fs_extra_1 = __importDefault(require("fs-extra"));
9
+ const path_1 = __importDefault(require("path"));
10
+ const tokens_1 = require("../utils/tokens");
11
+ async function indexCommand(options) {
12
+ console.log(chalk_1.default.blue('[INFO] Generating project index...'));
13
+ const depth = options.depth ? parseInt(options.depth) : 5;
14
+ const projectRoot = process.cwd();
15
+ const destDir = path_1.default.join(projectRoot, 'docs/ai');
16
+ const destFile = path_1.default.join(destDir, 'project-structure.md');
17
+ // Ensure docs/ai exists
18
+ await fs_extra_1.default.ensureDir(destDir);
19
+ try {
20
+ const tree = await (0, tokens_1.generateFileTree)(projectRoot, depth);
21
+ const tokens = (0, tokens_1.estimateTokens)(tree);
22
+ const content = `# Project Structure Index
23
+ <!--
24
+ GENERATED FILE - DO NOT EDIT MANUALLY
25
+ Generated by: contextuate index
26
+ Tokens: ~${tokens}
27
+ -->
28
+
29
+ \`\`\`
30
+ ${tree}
31
+ \`\`\`
32
+ `;
33
+ if (await fs_extra_1.default.pathExists(destFile) && !options.force) {
34
+ // Check if content is different? For now just overwrite if forced or tell user
35
+ // Actually, index is meant to be regenerated. We'll overwrite but log it.
36
+ // console.log(chalk.yellow(`[WARN] Overwriting existing index at ${destFile}`));
37
+ }
38
+ await fs_extra_1.default.writeFile(destFile, content);
39
+ console.log(chalk_1.default.green(`[OK] Generated index at: ${destFile}`));
40
+ console.log(` Size: ${chalk_1.default.cyan(tokens + ' tokens')} (approx)`);
41
+ console.log(` Use this file to give agents a high-level map of the codebase.`);
42
+ }
43
+ catch (e) {
44
+ console.error(chalk_1.default.red(`[ERROR] Failed to generate index: ${e.message}`));
45
+ }
46
+ }