@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.
- package/LICENSE +21 -0
- package/README.md +287 -0
- package/dist/commands/context.js +80 -0
- package/dist/commands/create.js +93 -0
- package/dist/commands/index.js +46 -0
- package/dist/commands/init.js +452 -0
- package/dist/commands/install.js +359 -0
- package/dist/commands/remove.js +77 -0
- package/dist/commands/run.js +205 -0
- package/dist/index.js +96 -0
- package/dist/runtime/driver.js +64 -0
- package/dist/runtime/tools.js +48 -0
- package/dist/templates/README.md +152 -0
- package/dist/templates/agents/aegis.md +366 -0
- package/dist/templates/agents/archon.md +247 -0
- package/dist/templates/agents/atlas.md +326 -0
- package/dist/templates/agents/canvas.md +19 -0
- package/dist/templates/agents/chronicle.md +424 -0
- package/dist/templates/agents/chronos.md +20 -0
- package/dist/templates/agents/cipher.md +360 -0
- package/dist/templates/agents/crucible.md +375 -0
- package/dist/templates/agents/echo.md +297 -0
- package/dist/templates/agents/forge.md +613 -0
- package/dist/templates/agents/ledger.md +317 -0
- package/dist/templates/agents/meridian.md +281 -0
- package/dist/templates/agents/nexus.md +600 -0
- package/dist/templates/agents/oracle.md +281 -0
- package/dist/templates/agents/scribe.md +612 -0
- package/dist/templates/agents/sentinel.md +312 -0
- package/dist/templates/agents/unity.md +17 -0
- package/dist/templates/agents/vox.md +19 -0
- package/dist/templates/agents/weaver.md +334 -0
- package/dist/templates/framework-agents/base.md +166 -0
- package/dist/templates/framework-agents/documentation-expert.md +292 -0
- package/dist/templates/framework-agents/tools-expert.md +245 -0
- package/dist/templates/standards/agent-roles.md +34 -0
- package/dist/templates/standards/agent-workflow.md +170 -0
- package/dist/templates/standards/behavioral-guidelines.md +145 -0
- package/dist/templates/standards/coding-standards.md +171 -0
- package/dist/templates/standards/task-workflow.md +246 -0
- package/dist/templates/templates/context.md +33 -0
- package/dist/templates/templates/contextuate.md +109 -0
- package/dist/templates/templates/platforms/AGENTS.md +5 -0
- package/dist/templates/templates/platforms/CLAUDE.md +5 -0
- package/dist/templates/templates/platforms/GEMINI.md +5 -0
- package/dist/templates/templates/platforms/clinerules.md +5 -0
- package/dist/templates/templates/platforms/copilot.md +5 -0
- package/dist/templates/templates/platforms/cursor.mdc +9 -0
- package/dist/templates/templates/platforms/windsurf.md +5 -0
- package/dist/templates/templates/standards/go.standards.md +167 -0
- package/dist/templates/templates/standards/java.standards.md +167 -0
- package/dist/templates/templates/standards/javascript.standards.md +292 -0
- package/dist/templates/templates/standards/php.standards.md +181 -0
- package/dist/templates/templates/standards/python.standards.md +175 -0
- package/dist/templates/tools/agent-creator.tool.md +252 -0
- package/dist/templates/tools/quickref.tool.md +216 -0
- package/dist/templates/tools/spawn.tool.md +31 -0
- package/dist/templates/tools/standards-detector.tool.md +301 -0
- package/dist/templates/version.json +8 -0
- package/dist/utils/git.js +62 -0
- package/dist/utils/tokens.js +74 -0
- package/package.json +59 -0
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
# Standards Detector Tool
|
|
2
|
+
|
|
3
|
+
> **Type:** AI Tool Guide
|
|
4
|
+
> **Purpose:** Analyze project files to detect and document coding standards
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## When to Use This Tool
|
|
9
|
+
|
|
10
|
+
Use this tool when:
|
|
11
|
+
- Setting up Contextuate in an existing project
|
|
12
|
+
- User wants coding standards documented
|
|
13
|
+
- Standards need to be inferred from existing code
|
|
14
|
+
- Creating project-specific coding standards
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Input
|
|
19
|
+
|
|
20
|
+
**Required:** Access to project source files
|
|
21
|
+
|
|
22
|
+
**Optional:**
|
|
23
|
+
- Specific languages to analyze
|
|
24
|
+
- Specific directories to focus on
|
|
25
|
+
- Existing style config files (.eslintrc, .prettierrc, phpcs.xml, etc.)
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Process
|
|
30
|
+
|
|
31
|
+
### Step 1: Detect Languages
|
|
32
|
+
|
|
33
|
+
Scan project for source files and identify languages:
|
|
34
|
+
|
|
35
|
+
| Extension | Language |
|
|
36
|
+
|-----------|----------|
|
|
37
|
+
| `.php` | PHP |
|
|
38
|
+
| `.js`, `.jsx` | JavaScript |
|
|
39
|
+
| `.ts`, `.tsx` | TypeScript |
|
|
40
|
+
| `.py` | Python |
|
|
41
|
+
| `.go` | Go |
|
|
42
|
+
| `.rb` | Ruby |
|
|
43
|
+
| `.java` | Java |
|
|
44
|
+
| `.cs` | C# |
|
|
45
|
+
| `.rs` | Rust |
|
|
46
|
+
|
|
47
|
+
### Step 2: Check for Config Files
|
|
48
|
+
|
|
49
|
+
Look for existing style configuration:
|
|
50
|
+
|
|
51
|
+
| File | Tool | Language |
|
|
52
|
+
|------|------|----------|
|
|
53
|
+
| `.eslintrc*` | ESLint | JS/TS |
|
|
54
|
+
| `.prettierrc*` | Prettier | JS/TS/CSS |
|
|
55
|
+
| `phpcs.xml` | PHP_CodeSniffer | PHP |
|
|
56
|
+
| `.php-cs-fixer.php` | PHP CS Fixer | PHP |
|
|
57
|
+
| `pyproject.toml` | Black/Ruff | Python |
|
|
58
|
+
| `.editorconfig` | EditorConfig | All |
|
|
59
|
+
| `tslint.json` | TSLint | TypeScript |
|
|
60
|
+
| `.rubocop.yml` | RuboCop | Ruby |
|
|
61
|
+
|
|
62
|
+
If config files exist, extract rules from them first.
|
|
63
|
+
|
|
64
|
+
### Step 3: Analyze Sample Files
|
|
65
|
+
|
|
66
|
+
For each detected language, read 3-5 representative files:
|
|
67
|
+
- Prefer files in `src/`, `app/`, `lib/` directories
|
|
68
|
+
- Choose files with 50-200 lines (not too short, not too long)
|
|
69
|
+
- Include different file types (classes, utilities, controllers)
|
|
70
|
+
|
|
71
|
+
### Step 4: Detect Patterns
|
|
72
|
+
|
|
73
|
+
For each file, analyze:
|
|
74
|
+
|
|
75
|
+
#### Formatting
|
|
76
|
+
- **Indentation:** Count leading whitespace characters
|
|
77
|
+
- All tabs → tabs
|
|
78
|
+
- 2 spaces → 2-space indent
|
|
79
|
+
- 4 spaces → 4-space indent
|
|
80
|
+
- **Braces:** Check if `{` appears on same line or next line
|
|
81
|
+
- **Spacing:** Check patterns inside parentheses, after keywords
|
|
82
|
+
- **Semicolons (JS):** Present at end of statements?
|
|
83
|
+
- **Quotes (JS):** Single or double quotes predominant?
|
|
84
|
+
|
|
85
|
+
#### Naming
|
|
86
|
+
- **Classes:** PascalCase, snake_case, etc.
|
|
87
|
+
- **Functions:** camelCase, snake_case, etc.
|
|
88
|
+
- **Variables:** camelCase, snake_case, etc.
|
|
89
|
+
- **Constants:** UPPER_CASE, camelCase, etc.
|
|
90
|
+
|
|
91
|
+
#### Structure
|
|
92
|
+
- **Import organization:** Grouped? Alphabetized?
|
|
93
|
+
- **File organization:** Class structure patterns
|
|
94
|
+
|
|
95
|
+
#### Documentation
|
|
96
|
+
- **DocBlocks:** Present? Format?
|
|
97
|
+
- **Comments:** Inline style?
|
|
98
|
+
|
|
99
|
+
### Step 5: Resolve Conflicts
|
|
100
|
+
|
|
101
|
+
If patterns vary across files:
|
|
102
|
+
1. Count occurrences of each pattern
|
|
103
|
+
2. Use majority pattern (60%+ agreement)
|
|
104
|
+
3. Note inconsistencies for user review
|
|
105
|
+
4. Flag if no clear majority exists
|
|
106
|
+
|
|
107
|
+
### Step 6: Generate Standards Document
|
|
108
|
+
|
|
109
|
+
Use the appropriate template from `templates/standards/`:
|
|
110
|
+
- `php.standards.md` for PHP
|
|
111
|
+
- `javascript.standards.md` for JS/TS
|
|
112
|
+
|
|
113
|
+
Fill in detected values, replacing `{placeholders}`.
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Output
|
|
118
|
+
|
|
119
|
+
Create files in `docs/ai/standards/` (user-customizable location):
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
docs/ai/standards/
|
|
123
|
+
├── php.standards.md # If PHP detected
|
|
124
|
+
├── javascript.standards.md # If JS/TS detected
|
|
125
|
+
└── {language}.standards.md # For other languages
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
These user standards take priority over framework defaults in `docs/ai/.context/templates/standards/`.
|
|
129
|
+
See [coding-standards.md](../standards/coding-standards.md) for resolution order.
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Analysis Checklist
|
|
134
|
+
|
|
135
|
+
### PHP Analysis
|
|
136
|
+
|
|
137
|
+
```php
|
|
138
|
+
// Check for:
|
|
139
|
+
// 1. Indentation
|
|
140
|
+
$line = " code"; // 4 spaces
|
|
141
|
+
$line = "\tcode"; // tab
|
|
142
|
+
|
|
143
|
+
// 2. Brace style
|
|
144
|
+
class Foo { // same-line
|
|
145
|
+
class Foo // next-line
|
|
146
|
+
{
|
|
147
|
+
|
|
148
|
+
// 3. Parentheses spacing
|
|
149
|
+
function foo( $param ) // spaces inside
|
|
150
|
+
function foo($param) // no spaces
|
|
151
|
+
|
|
152
|
+
// 4. Array syntax
|
|
153
|
+
$arr = array(); // long syntax
|
|
154
|
+
$arr = []; // short syntax
|
|
155
|
+
|
|
156
|
+
// 5. Visibility
|
|
157
|
+
public $prop; // explicit
|
|
158
|
+
var $prop; // implicit (old style)
|
|
159
|
+
|
|
160
|
+
// 6. Type hints
|
|
161
|
+
function foo( string $a ): int // yes
|
|
162
|
+
function foo( $a ) // no
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### JavaScript Analysis
|
|
166
|
+
|
|
167
|
+
```javascript
|
|
168
|
+
// Check for:
|
|
169
|
+
// 1. Semicolons
|
|
170
|
+
const x = 1; // with semicolon
|
|
171
|
+
const x = 1 // without
|
|
172
|
+
|
|
173
|
+
// 2. Quotes
|
|
174
|
+
'single quotes'
|
|
175
|
+
"double quotes"
|
|
176
|
+
|
|
177
|
+
// 3. Variable declaration
|
|
178
|
+
const x = 1; // const preferred
|
|
179
|
+
let x = 1; // let used
|
|
180
|
+
var x = 1; // var used (legacy)
|
|
181
|
+
|
|
182
|
+
// 4. Arrow functions
|
|
183
|
+
const fn = () => {}; // arrow
|
|
184
|
+
function fn() {} // declaration
|
|
185
|
+
|
|
186
|
+
// 5. Trailing commas
|
|
187
|
+
{ a: 1, b: 2, } // trailing
|
|
188
|
+
{ a: 1, b: 2 } // no trailing
|
|
189
|
+
|
|
190
|
+
// 6. Object shorthand
|
|
191
|
+
{ name: name } // verbose
|
|
192
|
+
{ name } // shorthand
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## Example Output
|
|
198
|
+
|
|
199
|
+
After analyzing a PHP project:
|
|
200
|
+
|
|
201
|
+
```markdown
|
|
202
|
+
# PHP Coding Standards
|
|
203
|
+
|
|
204
|
+
> **Language:** PHP
|
|
205
|
+
> **Generated:** 2024-01-15
|
|
206
|
+
> **Detected from:** src/Services/, src/Controllers/
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## Formatting
|
|
211
|
+
|
|
212
|
+
### Indentation
|
|
213
|
+
- **Style:** tabs
|
|
214
|
+
- **Size:** 1 tab
|
|
215
|
+
|
|
216
|
+
### Braces
|
|
217
|
+
- **Classes/Functions:** same-line
|
|
218
|
+
- **Control structures:** same-line
|
|
219
|
+
|
|
220
|
+
### Spacing
|
|
221
|
+
- **Inside parentheses:** yes - `function( $param )`
|
|
222
|
+
- **After keywords:** yes - `if( $x )`
|
|
223
|
+
- **Array brackets:** no-spaces - `$arr['key']`
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## Naming Conventions
|
|
228
|
+
|
|
229
|
+
### Classes
|
|
230
|
+
- **Style:** PascalCase
|
|
231
|
+
- **Example:** `UserService`, `PaymentController`
|
|
232
|
+
|
|
233
|
+
### Methods
|
|
234
|
+
- **Style:** camelCase
|
|
235
|
+
- **Example:** `getUserById()`, `processPayment()`
|
|
236
|
+
|
|
237
|
+
### Variables
|
|
238
|
+
- **Style:** snake_case
|
|
239
|
+
- **Example:** `$user_name`, `$is_active`
|
|
240
|
+
|
|
241
|
+
...
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## Edge Cases
|
|
247
|
+
|
|
248
|
+
### Mixed Standards
|
|
249
|
+
If project has inconsistent standards:
|
|
250
|
+
1. Document the majority pattern
|
|
251
|
+
2. Add a note about inconsistencies
|
|
252
|
+
3. Suggest the user choose one
|
|
253
|
+
|
|
254
|
+
```markdown
|
|
255
|
+
> **Note:** Mixed indentation detected (60% tabs, 40% 2-space).
|
|
256
|
+
> Documenting tabs as primary. Consider standardizing.
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### No Clear Pattern
|
|
260
|
+
If no pattern emerges:
|
|
261
|
+
1. Leave placeholder in template
|
|
262
|
+
2. Note that manual input is needed
|
|
263
|
+
|
|
264
|
+
```markdown
|
|
265
|
+
### Variables
|
|
266
|
+
- **Style:** {inconsistent - needs manual specification}
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### Config File Conflicts
|
|
270
|
+
If config files disagree with actual code:
|
|
271
|
+
1. Prefer config file settings (they're intentional)
|
|
272
|
+
2. Note that code may not follow config
|
|
273
|
+
3. Suggest running linter to fix
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## Reporting
|
|
278
|
+
|
|
279
|
+
After generating standards, report:
|
|
280
|
+
|
|
281
|
+
1. Languages detected
|
|
282
|
+
2. Files analyzed
|
|
283
|
+
3. Config files found
|
|
284
|
+
4. Standards documents created
|
|
285
|
+
5. Any inconsistencies or manual input needed
|
|
286
|
+
|
|
287
|
+
```
|
|
288
|
+
Standards Detection Complete
|
|
289
|
+
============================
|
|
290
|
+
Languages: PHP, JavaScript
|
|
291
|
+
Files analyzed: 12
|
|
292
|
+
Config files: .eslintrc.js, .editorconfig
|
|
293
|
+
|
|
294
|
+
Created:
|
|
295
|
+
- docs/ai/standards/php.standards.md
|
|
296
|
+
- docs/ai/standards/javascript.standards.md
|
|
297
|
+
|
|
298
|
+
Notes:
|
|
299
|
+
- PHP: Inconsistent variable naming (70% snake_case)
|
|
300
|
+
- JS: No semicolons detected, matches .eslintrc
|
|
301
|
+
```
|
|
@@ -0,0 +1,62 @@
|
|
|
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.GitManager = void 0;
|
|
7
|
+
const child_process_1 = require("child_process");
|
|
8
|
+
const util_1 = __importDefault(require("util"));
|
|
9
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const execAsync = util_1.default.promisify(child_process_1.exec);
|
|
12
|
+
class GitManager {
|
|
13
|
+
constructor(cwd) {
|
|
14
|
+
this.cwd = cwd;
|
|
15
|
+
}
|
|
16
|
+
async isGitRepo() {
|
|
17
|
+
try {
|
|
18
|
+
await execAsync('git rev-parse --is-inside-work-tree', { cwd: this.cwd });
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
async getCurrentBranch() {
|
|
26
|
+
const { stdout } = await execAsync('git rev-parse --abbrev-ref HEAD', { cwd: this.cwd });
|
|
27
|
+
return stdout.trim();
|
|
28
|
+
}
|
|
29
|
+
async createWorktree(agentName, sessionId) {
|
|
30
|
+
// Worktrees will be stored in .contextuate/worktrees/
|
|
31
|
+
const worktreeDir = path_1.default.join(this.cwd, '.contextuate/worktrees', `${agentName}-${sessionId}`);
|
|
32
|
+
const branchName = `agent/${agentName}/${sessionId}`;
|
|
33
|
+
// Ensure parent dir exists
|
|
34
|
+
await fs_extra_1.default.ensureDir(path_1.default.dirname(worktreeDir));
|
|
35
|
+
// Create worktree with a new branch
|
|
36
|
+
// -b creates the branch
|
|
37
|
+
await execAsync(`git worktree add -b ${branchName} "${worktreeDir}"`, { cwd: this.cwd });
|
|
38
|
+
return worktreeDir;
|
|
39
|
+
}
|
|
40
|
+
async removeWorktree(worktreePath, deleteBranch = false) {
|
|
41
|
+
await execAsync(`git worktree remove "${worktreePath}" --force`, { cwd: this.cwd });
|
|
42
|
+
if (deleteBranch) {
|
|
43
|
+
// Extract branch name from path? Or pass it in.
|
|
44
|
+
// For safety, maybe we don't auto-delete the branch by default so work is preserved.
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async commitChanges(worktreePath, message) {
|
|
48
|
+
try {
|
|
49
|
+
await execAsync('git add .', { cwd: worktreePath });
|
|
50
|
+
// check if there are changes
|
|
51
|
+
await execAsync(`git commit -m "${message}"`, { cwd: worktreePath });
|
|
52
|
+
}
|
|
53
|
+
catch (e) {
|
|
54
|
+
// If nothing to commit, that's fine
|
|
55
|
+
if (e.stdout && e.stdout.includes('nothing to commit')) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
throw e;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
exports.GitManager = GitManager;
|
|
@@ -0,0 +1,74 @@
|
|
|
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.estimateTokens = estimateTokens;
|
|
7
|
+
exports.generateFileTree = generateFileTree;
|
|
8
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
/**
|
|
11
|
+
* Estimates the number of tokens in a string.
|
|
12
|
+
* Uses a simple heuristic: ~4 characters per token for English text/code.
|
|
13
|
+
*/
|
|
14
|
+
function estimateTokens(text) {
|
|
15
|
+
return Math.ceil(text.length / 4);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Generates a compact file tree representation of a directory.
|
|
19
|
+
* Respects .gitignore via a simple filter (can be enhanced).
|
|
20
|
+
*/
|
|
21
|
+
async function generateFileTree(dir, maxDepth = 5) {
|
|
22
|
+
const lines = [];
|
|
23
|
+
// Load gitignore if present
|
|
24
|
+
const gitignorePath = path_1.default.join(dir, '.gitignore');
|
|
25
|
+
let ignorePatterns = ['.git', 'node_modules', 'dist', 'coverage', '.DS_Store'];
|
|
26
|
+
if (await fs_extra_1.default.pathExists(gitignorePath)) {
|
|
27
|
+
const content = await fs_extra_1.default.readFile(gitignorePath, 'utf-8');
|
|
28
|
+
const userIgnores = content.split('\n')
|
|
29
|
+
.map(l => l.trim())
|
|
30
|
+
.filter(l => l && !l.startsWith('#'));
|
|
31
|
+
ignorePatterns = [...ignorePatterns, ...userIgnores];
|
|
32
|
+
}
|
|
33
|
+
const isIgnored = (name) => {
|
|
34
|
+
// Very basic glob matching for common patterns
|
|
35
|
+
return ignorePatterns.some(pattern => {
|
|
36
|
+
const cleanPattern = pattern.replace(/\/$/, '').replace(/^\//, '');
|
|
37
|
+
if (pattern.startsWith('*'))
|
|
38
|
+
return name.endsWith(pattern.slice(1));
|
|
39
|
+
if (pattern.endsWith('*'))
|
|
40
|
+
return name.startsWith(pattern.slice(0, -1));
|
|
41
|
+
return name === cleanPattern || matchGlob(name, cleanPattern);
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
// Helper for simple glob matching
|
|
45
|
+
const matchGlob = (str, glob) => {
|
|
46
|
+
const regex = new RegExp('^' + glob.replace(/\./g, '\\.').replace(/\*/g, '.*') + '$');
|
|
47
|
+
return regex.test(str);
|
|
48
|
+
};
|
|
49
|
+
async function traverse(currentDir, currentDepth, prefix = '') {
|
|
50
|
+
if (currentDepth > maxDepth)
|
|
51
|
+
return;
|
|
52
|
+
const entries = await fs_extra_1.default.readdir(currentDir, { withFileTypes: true });
|
|
53
|
+
// Sort: directories first, then files
|
|
54
|
+
entries.sort((a, b) => {
|
|
55
|
+
if (a.isDirectory() === b.isDirectory())
|
|
56
|
+
return a.name.localeCompare(b.name);
|
|
57
|
+
return a.isDirectory() ? -1 : 1;
|
|
58
|
+
});
|
|
59
|
+
const filtered = entries.filter(e => !isIgnored(e.name));
|
|
60
|
+
for (let i = 0; i < filtered.length; i++) {
|
|
61
|
+
const entry = filtered[i];
|
|
62
|
+
const isLast = i === filtered.length - 1;
|
|
63
|
+
const marker = isLast ? '└── ' : '├── ';
|
|
64
|
+
lines.push(`${prefix}${marker}${entry.name}${entry.isDirectory() ? '/' : ''}`);
|
|
65
|
+
if (entry.isDirectory()) {
|
|
66
|
+
const newPrefix = prefix + (isLast ? ' ' : '│ ');
|
|
67
|
+
await traverse(path_1.default.join(currentDir, entry.name), currentDepth + 1, newPrefix);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
lines.push(path_1.default.basename(dir) + '/');
|
|
72
|
+
await traverse(dir, 1);
|
|
73
|
+
return lines.join('\n');
|
|
74
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@esotech/contextuate",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "**Standardized AI Context for Software Projects**",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"contextuate": "dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"directories": {
|
|
10
|
+
"doc": "docs"
|
|
11
|
+
},
|
|
12
|
+
"scripts": {
|
|
13
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
14
|
+
"build": "tsc && mkdir -p dist/templates && cp -r src/templates/* dist/templates/",
|
|
15
|
+
"prepublishOnly": "npm run build"
|
|
16
|
+
},
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/esotech/contextuate.git"
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist",
|
|
23
|
+
"docs/ai/.context"
|
|
24
|
+
],
|
|
25
|
+
"keywords": [
|
|
26
|
+
"ai",
|
|
27
|
+
"context",
|
|
28
|
+
"llm",
|
|
29
|
+
"agent",
|
|
30
|
+
"coding-assistant",
|
|
31
|
+
"copilot",
|
|
32
|
+
"cursor",
|
|
33
|
+
"anthropic",
|
|
34
|
+
"claude"
|
|
35
|
+
],
|
|
36
|
+
"author": "Alexander David Conroy <alex@esotech.com> (https://github.com/geilt)",
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"publishConfig": {
|
|
39
|
+
"access": "public"
|
|
40
|
+
},
|
|
41
|
+
"type": "commonjs",
|
|
42
|
+
"bugs": {
|
|
43
|
+
"url": "https://github.com/esotech/contextuate/issues"
|
|
44
|
+
},
|
|
45
|
+
"homepage": "https://contextuate.md",
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@types/fs-extra": "^11.0.4",
|
|
48
|
+
"@types/inquirer": "^9.0.9",
|
|
49
|
+
"@types/node": "^24.10.1",
|
|
50
|
+
"typescript": "^5.9.3"
|
|
51
|
+
},
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"chalk": "^5.6.2",
|
|
54
|
+
"commander": "^14.0.2",
|
|
55
|
+
"fs-extra": "^11.3.2",
|
|
56
|
+
"gray-matter": "^4.0.3",
|
|
57
|
+
"inquirer": "^13.0.1"
|
|
58
|
+
}
|
|
59
|
+
}
|