@p_tipso/agentive 1.0.0 → 1.0.1
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 +86 -55
- package/package.json +2 -2
- package/src/commands/init.js +25 -104
- package/src/templates/AGENTS.md +29 -0
- package/src/templates/commands/README.md +26 -0
- package/src/templates/commands/fix-issue.md +41 -0
- package/src/templates/commands/review.md +37 -0
- package/src/templates/rules/README.md +29 -0
- package/src/templates/skills/README.md +29 -0
- package/src/utils/compilers.js +22 -21
- package/src/utils/fileSystem.js +66 -41
- package/src/templates/context/project_overview.md +0 -62
- package/src/templates/rules/architecture.md +0 -42
- package/src/templates/skills/data-extractor.md +0 -56
- package/src/templates/skills/data-transformer.md +0 -62
- package/src/templates/skills/output-dispatcher.md +0 -79
- package/src/templates/skills/web-browser.md +0 -54
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
3
|
# 🤖 agentive
|
|
4
4
|
|
|
@@ -12,77 +12,123 @@
|
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
15
|
-
Stop maintaining separate rule files for every AI tool. **agentive** scaffolds a
|
|
15
|
+
Stop maintaining separate rule files for every AI tool. **agentive** scaffolds a universal `.agents/` directory and an `AGENTS.md` file in your project — your single source of truth for agent commands, skills, and rules.
|
|
16
16
|
|
|
17
17
|
## ✨ What it does
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
2. **Syncs** your `.agent/` files into the native formats of your chosen AI tools:
|
|
21
|
-
- 🖱 **Cursor** → `.cursor/rules/`
|
|
22
|
-
- 🤖 **Claude** → `CLAUDE.md`
|
|
23
|
-
- 🌊 **Windsurf** → `.windsurfrules`
|
|
24
|
-
|
|
25
|
-
---
|
|
26
|
-
|
|
27
|
-
## 🚀 Quick Start
|
|
19
|
+
Run one command, get a fully structured AI agent workspace:
|
|
28
20
|
|
|
29
21
|
```bash
|
|
30
22
|
npx @p_tipso/agentive
|
|
31
23
|
```
|
|
32
24
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
3. **Which AI tools** you use (multi-select: Cursor, Claude, Windsurf)
|
|
25
|
+
No prompts. No config. Just run it and it scaffolds everything instantly into the folder your terminal is currently in.
|
|
26
|
+
|
|
27
|
+
### What happens when you run it
|
|
37
28
|
|
|
38
|
-
|
|
29
|
+
1. Detects your current directory and project name
|
|
30
|
+
2. Creates an `AGENTS.md` file at your project root (top-level agent instructions)
|
|
31
|
+
3. Creates a `.agents/` folder with the full workspace structure:
|
|
32
|
+
- `settings.json` — project config (committed to git)
|
|
33
|
+
- `settings.local.json` — local machine overrides (auto-gitignored)
|
|
34
|
+
- `commands/` — reusable prompt commands (e.g. code review, fix errors)
|
|
35
|
+
- `skills/` — skill definitions for agent roles
|
|
36
|
+
- `rules/` — project-wide rules all agents must follow
|
|
37
|
+
4. If `.agents/` already exists, it skips to avoid overwriting your customisations
|
|
39
38
|
|
|
40
39
|
---
|
|
41
40
|
|
|
42
41
|
## 📁 Output Structure
|
|
43
42
|
|
|
44
|
-
After running `npx @p_tipso/agentive`, your project will have:
|
|
45
|
-
|
|
46
43
|
```
|
|
47
44
|
your-project/
|
|
48
|
-
├── .agent
|
|
49
|
-
|
|
50
|
-
│ ├── settings.
|
|
51
|
-
│ ├──
|
|
52
|
-
│
|
|
53
|
-
│
|
|
54
|
-
│
|
|
55
|
-
│
|
|
56
|
-
│
|
|
57
|
-
│
|
|
58
|
-
│
|
|
59
|
-
│
|
|
60
|
-
│
|
|
61
|
-
├── .cursor/rules/ ← if you selected Cursor
|
|
62
|
-
├── CLAUDE.md ← if you selected Claude
|
|
63
|
-
└── .windsurfrules ← if you selected Windsurf
|
|
45
|
+
├── AGENTS.md ← root agent instructions
|
|
46
|
+
├── .agents/
|
|
47
|
+
│ ├── settings.json ← project config
|
|
48
|
+
│ ├── settings.local.json ← local overrides (auto-gitignored)
|
|
49
|
+
│ ├── commands/
|
|
50
|
+
│ │ ├── README.md ← guide: how to add commands
|
|
51
|
+
│ │ ├── review.md ← code review command
|
|
52
|
+
│ │ └── fix-issue.md ← zero-error fix command
|
|
53
|
+
│ ├── skills/
|
|
54
|
+
│ │ └── README.md ← guide: how to add skills
|
|
55
|
+
│ └── rules/
|
|
56
|
+
│ └── README.md ← guide: how to add rules
|
|
64
57
|
```
|
|
65
58
|
|
|
66
|
-
### `settings.json`
|
|
59
|
+
### `settings.json`
|
|
67
60
|
|
|
68
61
|
```json
|
|
69
62
|
{
|
|
70
63
|
"projectName": "my-app",
|
|
71
|
-
"
|
|
72
|
-
"tools": ["cursor", "claude"],
|
|
73
|
-
"agentiveVersion": "1.0.0",
|
|
64
|
+
"agentiveVersion": "1.1.0",
|
|
74
65
|
"createdAt": "2026-07-05T12:00:00.000Z"
|
|
75
66
|
}
|
|
76
67
|
```
|
|
77
68
|
|
|
78
69
|
---
|
|
79
70
|
|
|
71
|
+
## 🏗 Package Architecture
|
|
72
|
+
|
|
73
|
+
This is the source code structure of the `agentive` npm package itself:
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
agentive/
|
|
77
|
+
├── bin/
|
|
78
|
+
│ └── index.js ← CLI entry point (shebang + commander)
|
|
79
|
+
├── src/
|
|
80
|
+
│ ├── commands/
|
|
81
|
+
│ │ └── init.js ← scaffolding logic (no prompts, auto-install)
|
|
82
|
+
│ ├── templates/ ← files copied into the user's project
|
|
83
|
+
│ │ ├── AGENTS.md ← → copied to project root
|
|
84
|
+
│ │ ├── commands/
|
|
85
|
+
│ │ │ ├── README.md
|
|
86
|
+
│ │ │ ├── review.md
|
|
87
|
+
│ │ │ └── fix-issue.md
|
|
88
|
+
│ │ ├── skills/
|
|
89
|
+
│ │ │ └── README.md
|
|
90
|
+
│ │ └── rules/
|
|
91
|
+
│ │ └── README.md
|
|
92
|
+
│ └── utils/
|
|
93
|
+
│ ├── fileSystem.js ← async fs helpers, directory creation, settings
|
|
94
|
+
│ └── compilers.js ← sync to Cursor / Claude / Windsurf formats
|
|
95
|
+
├── .github/
|
|
96
|
+
│ └── workflows/
|
|
97
|
+
│ └── publish.yml ← auto-publish to npm on git tag push
|
|
98
|
+
├── .gitignore
|
|
99
|
+
├── LICENSE
|
|
100
|
+
├── README.md
|
|
101
|
+
└── package.json
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## 📂 Folder Guide
|
|
107
|
+
|
|
108
|
+
### Commands (`commands/`)
|
|
109
|
+
|
|
110
|
+
Reusable prompt instructions that agents can execute on demand.
|
|
111
|
+
|
|
112
|
+
| File | Purpose |
|
|
113
|
+
|------|---------|
|
|
114
|
+
| `review.md` | Structured code review for bugs, performance, and security |
|
|
115
|
+
| `fix-issue.md` | Diagnose and fix errors with zero tolerance |
|
|
116
|
+
|
|
117
|
+
### Skills (`skills/`)
|
|
118
|
+
|
|
119
|
+
Skill definitions that teach agents how to behave in specific roles. Add `.md` files to define new capabilities.
|
|
120
|
+
|
|
121
|
+
### Rules (`rules/`)
|
|
122
|
+
|
|
123
|
+
Project-wide rules that all agents must follow. Add `.md` files for coding standards, architecture rules, etc.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
80
127
|
## 📦 Commands
|
|
81
128
|
|
|
82
129
|
| Command | Description |
|
|
83
130
|
|---|---|
|
|
84
|
-
| `npx @p_tipso/agentive` |
|
|
85
|
-
| `npx @p_tipso/agentive init` | Same as above (explicit subcommand) |
|
|
131
|
+
| `npx @p_tipso/agentive` | Scaffold `.agents/` workspace instantly |
|
|
86
132
|
| `npx @p_tipso/agentive --version` | Print the current version |
|
|
87
133
|
| `npx @p_tipso/agentive --help` | Show available commands |
|
|
88
134
|
|
|
@@ -90,8 +136,6 @@ your-project/
|
|
|
90
136
|
|
|
91
137
|
## 🛠 Install Globally (optional)
|
|
92
138
|
|
|
93
|
-
If you use this frequently, install it globally:
|
|
94
|
-
|
|
95
139
|
```bash
|
|
96
140
|
npm install -g @p_tipso/agentive
|
|
97
141
|
agentive
|
|
@@ -99,18 +143,6 @@ agentive
|
|
|
99
143
|
|
|
100
144
|
---
|
|
101
145
|
|
|
102
|
-
## 🔄 Re-syncing
|
|
103
|
-
|
|
104
|
-
Edited your `.agent/` files and want to push changes to Cursor, Claude, etc.? Just re-run:
|
|
105
|
-
|
|
106
|
-
```bash
|
|
107
|
-
npx @p_tipso/agentive
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
It will detect the existing `.agent/` directory and ask before overwriting.
|
|
111
|
-
|
|
112
|
-
---
|
|
113
|
-
|
|
114
146
|
## 🤝 Contributing
|
|
115
147
|
|
|
116
148
|
1. Fork the repo: [github.com/TiPS0/agentive](https://github.com/TiPS0/agentive)
|
|
@@ -124,4 +156,3 @@ It will detect the existing `.agent/` directory and ask before overwriting.
|
|
|
124
156
|
## 📄 License
|
|
125
157
|
|
|
126
158
|
MIT © [Pakawat Tipso](https://github.com/TiPS0)
|
|
127
|
-
]]>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@p_tipso/agentive",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "A universal, framework-agnostic AI agent repository setup CLI. Scaffold a .agent/ workspace and sync to Cursor, Claude, and Windsurf.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Pakawat Tipso",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"type": "git",
|
|
34
34
|
"url": "git+https://github.com/TiPS0/agentive.git"
|
|
35
35
|
},
|
|
36
|
-
"homepage": "https://github.com/TiPS0/agentive
|
|
36
|
+
"homepage": "https://github.com/TiPS0/agentive",
|
|
37
37
|
"bugs": {
|
|
38
38
|
"url": "https://github.com/TiPS0/agentive/issues"
|
|
39
39
|
},
|
package/src/commands/init.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const path = require('path');
|
|
4
|
-
const prompts = require('prompts');
|
|
5
4
|
const chalk = require('chalk');
|
|
6
5
|
const { version } = require('../../package.json');
|
|
7
6
|
const {
|
|
@@ -10,138 +9,60 @@ const {
|
|
|
10
9
|
agentDirectoryExists,
|
|
11
10
|
writeSettings,
|
|
12
11
|
} = require('../utils/fileSystem');
|
|
13
|
-
const { syncToCursor, syncToClaude, syncToWindsurf } = require('../utils/compilers');
|
|
14
|
-
|
|
15
|
-
const AI_TOOLS = [
|
|
16
|
-
{ title: '🖱 Cursor', value: 'cursor', description: 'Generates .cursor/rules/' },
|
|
17
|
-
{ title: '🤖 Claude', value: 'claude', description: 'Generates CLAUDE.md' },
|
|
18
|
-
{ title: '🌊 Windsurf', value: 'windsurf', description: 'Generates .windsurfrules' },
|
|
19
|
-
];
|
|
20
12
|
|
|
21
13
|
async function runInit() {
|
|
22
14
|
const cwd = process.cwd();
|
|
15
|
+
const projectName = path.basename(cwd);
|
|
23
16
|
|
|
24
17
|
console.log('');
|
|
25
18
|
console.log(chalk.bold.cyan(' 🤖 agentive') + chalk.gray(' — Universal AI Agent Workspace Setup'));
|
|
26
19
|
console.log(chalk.gray(' ─────────────────────────────────────────────'));
|
|
27
20
|
console.log('');
|
|
28
21
|
|
|
29
|
-
// --- Guard: check if .
|
|
22
|
+
// --- Guard: check if .agents/ already exists ---
|
|
30
23
|
const alreadyExists = await agentDirectoryExists(cwd);
|
|
31
24
|
if (alreadyExists) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
initial: false,
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
if (!overwrite) {
|
|
40
|
-
console.log('');
|
|
41
|
-
console.log(chalk.gray(' Aborted. Your existing .agent/ directory was not modified.'));
|
|
42
|
-
console.log('');
|
|
43
|
-
process.exit(0);
|
|
44
|
-
}
|
|
25
|
+
console.log(chalk.yellow(' ⚠ ') + chalk.white('.agents/ already exists — skipping (no files were modified).'));
|
|
26
|
+
console.log(chalk.gray(' Delete .agents/ first if you want to re-scaffold.'));
|
|
27
|
+
console.log('');
|
|
28
|
+
process.exit(0);
|
|
45
29
|
}
|
|
46
30
|
|
|
47
|
-
|
|
48
|
-
const projectName = path.basename(cwd);
|
|
49
|
-
|
|
50
|
-
const answers = await prompts(
|
|
51
|
-
[
|
|
52
|
-
{
|
|
53
|
-
type: 'text',
|
|
54
|
-
name: 'projectName',
|
|
55
|
-
message: 'Project name?',
|
|
56
|
-
initial: projectName,
|
|
57
|
-
validate: (v) => v.trim().length > 0 || 'Required.',
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
type: 'text',
|
|
61
|
-
name: 'techStack',
|
|
62
|
-
message: 'Primary tech stack?',
|
|
63
|
-
placeholder: 'e.g. Next.js, TypeScript, PostgreSQL',
|
|
64
|
-
validate: (v) => v.trim().length > 0 || 'Required.',
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
type: 'multiselect',
|
|
68
|
-
name: 'tools',
|
|
69
|
-
message: 'Which AI tools do you want to target?',
|
|
70
|
-
choices: AI_TOOLS,
|
|
71
|
-
min: 1,
|
|
72
|
-
hint: '- Space to select. Return to submit',
|
|
73
|
-
instructions: false,
|
|
74
|
-
},
|
|
75
|
-
],
|
|
76
|
-
{
|
|
77
|
-
onCancel: () => {
|
|
78
|
-
console.log('');
|
|
79
|
-
console.log(chalk.gray(' Setup cancelled.'));
|
|
80
|
-
process.exit(0);
|
|
81
|
-
},
|
|
82
|
-
}
|
|
83
|
-
);
|
|
84
|
-
|
|
85
|
-
const { tools, techStack } = answers;
|
|
86
|
-
const finalProjectName = answers.projectName;
|
|
87
|
-
|
|
88
|
-
console.log('');
|
|
89
|
-
console.log(chalk.gray(' Setting up your workspace...'));
|
|
31
|
+
console.log(chalk.gray(' Installing to: ') + chalk.white(cwd));
|
|
90
32
|
console.log('');
|
|
91
33
|
|
|
92
|
-
// --- Scaffold .
|
|
34
|
+
// --- Scaffold .agents/ directory ---
|
|
93
35
|
const templatesDir = path.join(__dirname, '..', 'templates');
|
|
94
|
-
const
|
|
95
|
-
await copyTemplates(templatesDir,
|
|
36
|
+
const agentsDir = await createAgentDirectory(cwd, false);
|
|
37
|
+
await copyTemplates(templatesDir, agentsDir, projectName);
|
|
96
38
|
|
|
97
39
|
// --- Write settings.json and settings.local.json ---
|
|
98
|
-
await writeSettings(
|
|
99
|
-
projectName
|
|
100
|
-
techStack,
|
|
101
|
-
tools,
|
|
40
|
+
await writeSettings(agentsDir, {
|
|
41
|
+
projectName,
|
|
102
42
|
agentiveVersion: version,
|
|
103
43
|
createdAt: new Date().toISOString(),
|
|
104
44
|
});
|
|
105
45
|
|
|
106
|
-
console.log(chalk.green(' ✔ ') + chalk.white('
|
|
107
|
-
|
|
108
|
-
// --- Sync to selected tools ---
|
|
109
|
-
const compilers = {
|
|
110
|
-
cursor: syncToCursor,
|
|
111
|
-
claude: syncToClaude,
|
|
112
|
-
windsurf: syncToWindsurf,
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
const toolLabels = {
|
|
116
|
-
cursor: '.cursor/rules/',
|
|
117
|
-
claude: 'CLAUDE.md',
|
|
118
|
-
windsurf: '.windsurfrules',
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
for (const tool of tools) {
|
|
122
|
-
try {
|
|
123
|
-
await compilers[tool](agentDir, cwd, techStack);
|
|
124
|
-
console.log(chalk.green(' ✔ ') + chalk.white('Synced → ') + chalk.cyan(toolLabels[tool]));
|
|
125
|
-
} catch (err) {
|
|
126
|
-
console.log(chalk.red(' ✘ ') + chalk.white(`Failed to sync ${tool}: `) + chalk.gray(err.message));
|
|
127
|
-
}
|
|
128
|
-
}
|
|
46
|
+
console.log(chalk.green(' ✔ ') + chalk.white('Created ') + chalk.cyan('AGENTS.md'));
|
|
47
|
+
console.log(chalk.green(' ✔ ') + chalk.white('Scaffolded ') + chalk.cyan('.agents/') + chalk.white(' workspace'));
|
|
129
48
|
|
|
130
49
|
// --- Done ---
|
|
131
50
|
console.log('');
|
|
132
51
|
console.log(chalk.bold.green(' ✅ All done!'));
|
|
133
52
|
console.log('');
|
|
134
|
-
console.log(chalk.white(' Your AI workspace is ready
|
|
53
|
+
console.log(chalk.white(' Your AI workspace is ready:'));
|
|
135
54
|
console.log('');
|
|
136
|
-
console.log(chalk.gray('
|
|
137
|
-
console.log(chalk.gray(' .
|
|
138
|
-
console.log(chalk.gray(' ├── settings.json
|
|
139
|
-
console.log(chalk.gray(' ├── settings.local.json
|
|
140
|
-
console.log(chalk.gray(' ├──
|
|
141
|
-
console.log(chalk.gray('
|
|
55
|
+
console.log(chalk.gray(' AGENTS.md ← root agent instructions'));
|
|
56
|
+
console.log(chalk.gray(' .agents/'));
|
|
57
|
+
console.log(chalk.gray(' ├── settings.json ← project config'));
|
|
58
|
+
console.log(chalk.gray(' ├── settings.local.json ← local overrides (gitignored)'));
|
|
59
|
+
console.log(chalk.gray(' ├── commands/'));
|
|
60
|
+
console.log(chalk.gray(' │ ├── review.md ← code review command'));
|
|
61
|
+
console.log(chalk.gray(' │ └── fix-issue.md ← zero-error fix command'));
|
|
62
|
+
console.log(chalk.gray(' ├── skills/'));
|
|
63
|
+
console.log(chalk.gray(' └── rules/'));
|
|
142
64
|
console.log('');
|
|
143
|
-
console.log(chalk.gray(' Edit the markdown files
|
|
144
|
-
console.log(chalk.gray(' Re-run ') + chalk.cyan('npx @p_tipso/agentive') + chalk.gray(' any time to re-sync to your AI tools.'));
|
|
65
|
+
console.log(chalk.gray(' Edit the markdown files to customise agent behaviour.'));
|
|
145
66
|
console.log('');
|
|
146
67
|
}
|
|
147
68
|
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Agent Instructions
|
|
2
|
+
|
|
3
|
+
> This file is your project's top-level instruction file for AI agents.
|
|
4
|
+
> It is generated by [agentive](https://github.com/TiPS0/agentive).
|
|
5
|
+
|
|
6
|
+
## Project
|
|
7
|
+
|
|
8
|
+
- **Name:** {{PROJECT_NAME}}
|
|
9
|
+
|
|
10
|
+
## Agent Configuration
|
|
11
|
+
|
|
12
|
+
All agent configuration lives inside the `.agents/` directory:
|
|
13
|
+
|
|
14
|
+
| Path | Purpose |
|
|
15
|
+
|------|---------|
|
|
16
|
+
| `.agents/settings.json` | Project-wide agent configuration (commit this) |
|
|
17
|
+
| `.agents/settings.local.json` | Local machine overrides (gitignored) |
|
|
18
|
+
| `.agents/commands/` | Reusable prompt commands your agents can execute |
|
|
19
|
+
| `.agents/skills/` | Skill definitions that teach agents how to behave |
|
|
20
|
+
| `.agents/rules/` | Project-wide rules all agents must follow |
|
|
21
|
+
|
|
22
|
+
## Getting Started
|
|
23
|
+
|
|
24
|
+
1. Edit the markdown files inside `.agents/` to customise agent behaviour
|
|
25
|
+
2. Add new commands in `.agents/commands/` for common tasks
|
|
26
|
+
3. Add new skills in `.agents/skills/` to teach agents new capabilities
|
|
27
|
+
4. Add new rules in `.agents/rules/` to enforce coding standards
|
|
28
|
+
|
|
29
|
+
Re-run `npx @p_tipso/agentive` any time to re-sync changes to your AI tools.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Commands
|
|
2
|
+
|
|
3
|
+
This folder contains **reusable prompt commands** — predefined instructions that AI agents can execute on demand.
|
|
4
|
+
|
|
5
|
+
## How to use
|
|
6
|
+
|
|
7
|
+
Each `.md` file in this directory is a command. To use a command, reference it by name when prompting your AI agent.
|
|
8
|
+
|
|
9
|
+
## Structure
|
|
10
|
+
|
|
11
|
+
Each command file should include:
|
|
12
|
+
|
|
13
|
+
- **Goal:** What the command achieves
|
|
14
|
+
- **Steps:** The ordered steps the agent should follow
|
|
15
|
+
- **Output:** What the agent should produce at the end
|
|
16
|
+
|
|
17
|
+
## Examples
|
|
18
|
+
|
|
19
|
+
| File | Purpose |
|
|
20
|
+
|------|---------|
|
|
21
|
+
| `review.md` | Review code for bugs, performance, and best practices |
|
|
22
|
+
| `fix-issue.md` | Diagnose and fix code errors with zero tolerance |
|
|
23
|
+
|
|
24
|
+
## Adding new commands
|
|
25
|
+
|
|
26
|
+
Create a new `.md` file in this folder. Name it clearly (e.g., `write-tests.md`, `refactor.md`, `deploy-check.md`).
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Command: Fix Issue (Zero Code Error)
|
|
2
|
+
|
|
3
|
+
> Use this command to diagnose and fix code errors with zero tolerance — no errors should remain after execution.
|
|
4
|
+
|
|
5
|
+
## Goal
|
|
6
|
+
|
|
7
|
+
Find and fix **all** code errors in the target file or project. The end result must compile, run, and pass all existing tests with zero errors.
|
|
8
|
+
|
|
9
|
+
## Steps
|
|
10
|
+
|
|
11
|
+
1. **Identify the error** — read the error message, stack trace, or failing test output
|
|
12
|
+
2. **Locate the root cause** — trace the error to its origin (don't just fix the symptom)
|
|
13
|
+
3. **Understand the context** — read surrounding code to understand the intended behaviour
|
|
14
|
+
4. **Implement the fix** — make the minimal change that resolves the root cause
|
|
15
|
+
5. **Check for side effects** — ensure the fix doesn't break other functionality
|
|
16
|
+
6. **Verify** — confirm the error is resolved by running the relevant command or test
|
|
17
|
+
|
|
18
|
+
## Rules
|
|
19
|
+
|
|
20
|
+
- **Never** suppress or silence errors without fixing the underlying cause
|
|
21
|
+
- **Never** add `// @ts-ignore`, `eslint-disable`, or similar without explicit approval
|
|
22
|
+
- **Prefer** targeted fixes over large refactors
|
|
23
|
+
- **Always** explain what caused the error and why the fix resolves it
|
|
24
|
+
|
|
25
|
+
## Output
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
### Error
|
|
29
|
+
[Original error message or description]
|
|
30
|
+
|
|
31
|
+
### Root Cause
|
|
32
|
+
[Explanation of why this error occurred]
|
|
33
|
+
|
|
34
|
+
### Fix Applied
|
|
35
|
+
[Description of what was changed and where]
|
|
36
|
+
|
|
37
|
+
### Verification
|
|
38
|
+
[How the fix was verified — command run, test passed, etc.]
|
|
39
|
+
|
|
40
|
+
### Status: ✅ Resolved
|
|
41
|
+
```
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Command: Review Code
|
|
2
|
+
|
|
3
|
+
> Use this command to perform a thorough code review on a file, folder, or pull request.
|
|
4
|
+
|
|
5
|
+
## Goal
|
|
6
|
+
|
|
7
|
+
Review the target code for correctness, performance, readability, and adherence to project conventions.
|
|
8
|
+
|
|
9
|
+
## Steps
|
|
10
|
+
|
|
11
|
+
1. **Read** the target code carefully from start to finish
|
|
12
|
+
2. **Check for bugs** — logic errors, off-by-one errors, null/undefined handling, race conditions
|
|
13
|
+
3. **Check for performance** — unnecessary re-renders, N+1 queries, missing indexes, memory leaks
|
|
14
|
+
4. **Check for security** — injection vulnerabilities, exposed secrets, missing auth checks
|
|
15
|
+
5. **Check for readability** — naming, function length, comment quality, dead code
|
|
16
|
+
6. **Check for conventions** — does the code follow the rules defined in `.agents/rules/`?
|
|
17
|
+
|
|
18
|
+
## Output
|
|
19
|
+
|
|
20
|
+
Provide a structured review with:
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
### Summary
|
|
24
|
+
One-sentence verdict (e.g., "Generally solid, 2 bugs found")
|
|
25
|
+
|
|
26
|
+
### Issues Found
|
|
27
|
+
- 🐛 **Bug:** [description] (file:line)
|
|
28
|
+
- ⚡ **Performance:** [description] (file:line)
|
|
29
|
+
- 🔒 **Security:** [description] (file:line)
|
|
30
|
+
|
|
31
|
+
### Suggestions
|
|
32
|
+
- 💡 [optional improvement]
|
|
33
|
+
|
|
34
|
+
### Verdict
|
|
35
|
+
- [ ] Ready to merge
|
|
36
|
+
- [ ] Needs changes (see issues above)
|
|
37
|
+
```
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Rules
|
|
2
|
+
|
|
3
|
+
This folder contains **project-wide rules** — constraints and standards that all AI agents must follow when working in this repository.
|
|
4
|
+
|
|
5
|
+
## How to use
|
|
6
|
+
|
|
7
|
+
Each `.md` file in this directory defines a set of rules. Agents will read and adhere to these rules for every task they perform.
|
|
8
|
+
|
|
9
|
+
## Structure
|
|
10
|
+
|
|
11
|
+
Each rule file should include:
|
|
12
|
+
|
|
13
|
+
- **Purpose:** Why this rule exists
|
|
14
|
+
- **Rules:** The specific constraints, listed clearly
|
|
15
|
+
- **Examples:** Good vs. bad patterns (optional but recommended)
|
|
16
|
+
|
|
17
|
+
## Examples of rules you could add
|
|
18
|
+
|
|
19
|
+
| File | Purpose |
|
|
20
|
+
|------|---------|
|
|
21
|
+
| `code-style.md` | Naming conventions, formatting, and patterns |
|
|
22
|
+
| `architecture.md` | How the project is structured, what goes where |
|
|
23
|
+
| `testing.md` | Testing requirements, coverage expectations |
|
|
24
|
+
| `security.md` | Security practices, data handling rules |
|
|
25
|
+
| `git.md` | Branch naming, commit messages, PR conventions |
|
|
26
|
+
|
|
27
|
+
## Adding new rules
|
|
28
|
+
|
|
29
|
+
Create a new `.md` file in this folder. Name it after the topic (e.g., `error-handling.md`, `performance.md`).
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Skills
|
|
2
|
+
|
|
3
|
+
This folder contains **skill definitions** — instructions that teach AI agents how to behave in specific roles or capabilities.
|
|
4
|
+
|
|
5
|
+
## How to use
|
|
6
|
+
|
|
7
|
+
Each `.md` file in this directory defines a skill. The agent will adopt the role described in the skill file when activated.
|
|
8
|
+
|
|
9
|
+
## Structure
|
|
10
|
+
|
|
11
|
+
Each skill file should include:
|
|
12
|
+
|
|
13
|
+
- **Role description:** What the agent does in this role
|
|
14
|
+
- **Responsibilities:** Specific tasks the agent handles
|
|
15
|
+
- **Inputs / Outputs:** What the agent expects and what it produces
|
|
16
|
+
- **Constraints:** Boundaries the agent must respect
|
|
17
|
+
|
|
18
|
+
## Examples of skills you could add
|
|
19
|
+
|
|
20
|
+
| File | Purpose |
|
|
21
|
+
|------|---------|
|
|
22
|
+
| `web-browser.md` | How agents should browse the web and retrieve data |
|
|
23
|
+
| `data-extractor.md` | How agents should extract structured data from raw content |
|
|
24
|
+
| `code-writer.md` | How agents should write new code following project conventions |
|
|
25
|
+
| `tester.md` | How agents should write and run tests |
|
|
26
|
+
|
|
27
|
+
## Adding new skills
|
|
28
|
+
|
|
29
|
+
Create a new `.md` file in this folder. Name it after the role (e.g., `api-designer.md`, `database-manager.md`).
|
package/src/utils/compilers.js
CHANGED
|
@@ -7,6 +7,7 @@ const path = require('path');
|
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Read all .md files from a directory and return their concatenated content.
|
|
10
|
+
* Skips README.md files since those are directory documentation, not agent rules.
|
|
10
11
|
* @param {string} dir
|
|
11
12
|
* @returns {Promise<string>}
|
|
12
13
|
*/
|
|
@@ -15,7 +16,7 @@ async function readMarkdownDir(dir) {
|
|
|
15
16
|
try {
|
|
16
17
|
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
17
18
|
for (const entry of entries) {
|
|
18
|
-
if (entry.isFile() && entry.name.endsWith('.md')) {
|
|
19
|
+
if (entry.isFile() && entry.name.endsWith('.md') && entry.name !== 'README.md') {
|
|
19
20
|
const filePath = path.join(dir, entry.name);
|
|
20
21
|
const fileContent = await fs.readFile(filePath, 'utf-8');
|
|
21
22
|
const section = entry.name.replace('.md', '').replace(/-/g, ' ');
|
|
@@ -57,12 +58,12 @@ async function copyDir(src, dest) {
|
|
|
57
58
|
// ─── Cursor ──────────────────────────────────────────────────────────────────
|
|
58
59
|
|
|
59
60
|
/**
|
|
60
|
-
* Sync .
|
|
61
|
-
* @param {string}
|
|
61
|
+
* Sync .agents/rules/ → .cursor/rules/
|
|
62
|
+
* @param {string} agentsDir
|
|
62
63
|
* @param {string} cwd
|
|
63
64
|
*/
|
|
64
|
-
async function syncToCursor(
|
|
65
|
-
const src = path.join(
|
|
65
|
+
async function syncToCursor(agentsDir, cwd) {
|
|
66
|
+
const src = path.join(agentsDir, 'rules');
|
|
66
67
|
const dest = path.join(cwd, '.cursor', 'rules');
|
|
67
68
|
await copyDir(src, dest);
|
|
68
69
|
}
|
|
@@ -70,19 +71,19 @@ async function syncToCursor(agentDir, cwd) {
|
|
|
70
71
|
// ─── Claude ──────────────────────────────────────────────────────────────────
|
|
71
72
|
|
|
72
73
|
/**
|
|
73
|
-
* Compile .
|
|
74
|
-
* @param {string}
|
|
74
|
+
* Compile .agents/ into a single CLAUDE.md file.
|
|
75
|
+
* @param {string} agentsDir
|
|
75
76
|
* @param {string} cwd
|
|
76
77
|
* @param {string} techStack
|
|
77
78
|
*/
|
|
78
|
-
async function syncToClaude(
|
|
79
|
-
const rulesContent
|
|
80
|
-
const
|
|
79
|
+
async function syncToClaude(agentsDir, cwd, techStack) {
|
|
80
|
+
const rulesContent = await readMarkdownDir(path.join(agentsDir, 'rules'));
|
|
81
|
+
const commandsContent = await readMarkdownDir(path.join(agentsDir, 'commands'));
|
|
81
82
|
|
|
82
83
|
const claudeMd = `# CLAUDE.md — AI Agent Instructions
|
|
83
84
|
|
|
84
85
|
> This file was auto-generated by [agentive](https://github.com/TiPS0/agentive).
|
|
85
|
-
> Edit the source files in \`.
|
|
86
|
+
> Edit the source files in \`.agents/\` and re-run \`npx @p_tipso/agentive\` to regenerate.
|
|
86
87
|
|
|
87
88
|
## Project Context
|
|
88
89
|
|
|
@@ -91,8 +92,8 @@ async function syncToClaude(agentDir, cwd, techStack) {
|
|
|
91
92
|
# Rules
|
|
92
93
|
${rulesContent}
|
|
93
94
|
|
|
94
|
-
#
|
|
95
|
-
${
|
|
95
|
+
# Commands
|
|
96
|
+
${commandsContent}
|
|
96
97
|
`.trim();
|
|
97
98
|
|
|
98
99
|
await fs.writeFile(path.join(cwd, 'CLAUDE.md'), claudeMd, 'utf-8');
|
|
@@ -101,27 +102,27 @@ ${skillsContent}
|
|
|
101
102
|
// ─── Windsurf ────────────────────────────────────────────────────────────────
|
|
102
103
|
|
|
103
104
|
/**
|
|
104
|
-
* Compile .
|
|
105
|
-
* @param {string}
|
|
105
|
+
* Compile .agents/rules/ into a single .windsurfrules file.
|
|
106
|
+
* @param {string} agentsDir
|
|
106
107
|
* @param {string} cwd
|
|
107
108
|
* @param {string} techStack
|
|
108
109
|
*/
|
|
109
|
-
async function syncToWindsurf(
|
|
110
|
-
const rulesContent
|
|
111
|
-
const
|
|
110
|
+
async function syncToWindsurf(agentsDir, cwd, techStack) {
|
|
111
|
+
const rulesContent = await readMarkdownDir(path.join(agentsDir, 'rules'));
|
|
112
|
+
const commandsContent = await readMarkdownDir(path.join(agentsDir, 'commands'));
|
|
112
113
|
|
|
113
114
|
const windsurfRules = `# .windsurfrules — AI Agent Instructions
|
|
114
115
|
|
|
115
116
|
> Auto-generated by [agentive](https://github.com/TiPS0/agentive).
|
|
116
|
-
> Edit \`.
|
|
117
|
+
> Edit \`.agents/\` and re-run \`npx @p_tipso/agentive\` to regenerate.
|
|
117
118
|
|
|
118
119
|
**Tech Stack:** ${techStack}
|
|
119
120
|
|
|
120
121
|
# Rules
|
|
121
122
|
${rulesContent}
|
|
122
123
|
|
|
123
|
-
#
|
|
124
|
-
${
|
|
124
|
+
# Commands
|
|
125
|
+
${commandsContent}
|
|
125
126
|
`.trim();
|
|
126
127
|
|
|
127
128
|
await fs.writeFile(path.join(cwd, '.windsurfrules'), windsurfRules, 'utf-8');
|
package/src/utils/fileSystem.js
CHANGED
|
@@ -6,13 +6,13 @@ const path = require('path');
|
|
|
6
6
|
// ─── Guards ──────────────────────────────────────────────────────────────────
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
* Check if a .
|
|
9
|
+
* Check if a .agents/ directory already exists in the given working directory.
|
|
10
10
|
* @param {string} cwd
|
|
11
11
|
* @returns {Promise<boolean>}
|
|
12
12
|
*/
|
|
13
13
|
async function agentDirectoryExists(cwd) {
|
|
14
14
|
try {
|
|
15
|
-
await fs.access(path.join(cwd, '.
|
|
15
|
+
await fs.access(path.join(cwd, '.agents'));
|
|
16
16
|
return true;
|
|
17
17
|
} catch {
|
|
18
18
|
return false;
|
|
@@ -22,57 +22,61 @@ async function agentDirectoryExists(cwd) {
|
|
|
22
22
|
// ─── Directory Creation ───────────────────────────────────────────────────────
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
|
-
* Create (or recreate) the .
|
|
25
|
+
* Create (or recreate) the .agents/ directory structure inside the user's project.
|
|
26
26
|
*
|
|
27
27
|
* Structure:
|
|
28
|
-
* .
|
|
28
|
+
* AGENTS.md ← project root
|
|
29
|
+
* .agents/
|
|
29
30
|
* ├── settings.json
|
|
30
31
|
* ├── settings.local.json
|
|
31
|
-
* ├──
|
|
32
|
-
*
|
|
32
|
+
* ├── commands/
|
|
33
|
+
* ├── skills/
|
|
34
|
+
* └── rules/
|
|
33
35
|
*
|
|
34
36
|
* @param {string} cwd - The user's current working directory
|
|
35
|
-
* @param {boolean} overwrite - Whether to remove an existing .
|
|
36
|
-
* @returns {Promise<string>} The path to the created .
|
|
37
|
+
* @param {boolean} overwrite - Whether to remove an existing .agents/ directory first
|
|
38
|
+
* @returns {Promise<string>} The path to the created .agents/ directory
|
|
37
39
|
*/
|
|
38
40
|
async function createAgentDirectory(cwd, overwrite = false) {
|
|
39
|
-
const
|
|
41
|
+
const agentsDir = path.join(cwd, '.agents');
|
|
40
42
|
|
|
41
43
|
if (overwrite) {
|
|
42
|
-
await fs.rm(
|
|
44
|
+
await fs.rm(agentsDir, { recursive: true, force: true });
|
|
45
|
+
// Also remove old AGENTS.md if overwriting
|
|
46
|
+
try { await fs.rm(path.join(cwd, 'AGENTS.md'), { force: true }); } catch { /* noop */ }
|
|
43
47
|
}
|
|
44
48
|
|
|
45
|
-
await fs.mkdir(
|
|
46
|
-
await fs.mkdir(path.join(
|
|
47
|
-
await fs.mkdir(path.join(
|
|
49
|
+
await fs.mkdir(agentsDir, { recursive: true });
|
|
50
|
+
await fs.mkdir(path.join(agentsDir, 'commands'), { recursive: true });
|
|
51
|
+
await fs.mkdir(path.join(agentsDir, 'skills'), { recursive: true });
|
|
52
|
+
await fs.mkdir(path.join(agentsDir, 'rules'), { recursive: true });
|
|
48
53
|
|
|
49
|
-
return
|
|
54
|
+
return agentsDir;
|
|
50
55
|
}
|
|
51
56
|
|
|
52
57
|
// ─── Settings Files ───────────────────────────────────────────────────────────
|
|
53
58
|
|
|
54
59
|
/**
|
|
55
|
-
* Write settings.json and settings.local.json inside .
|
|
60
|
+
* Write settings.json and settings.local.json inside .agents/.
|
|
56
61
|
*
|
|
57
62
|
* - settings.json → tracked by git (project-wide config)
|
|
58
63
|
* - settings.local.json → gitignored (machine-specific overrides)
|
|
59
64
|
*
|
|
60
|
-
* Also appends `.
|
|
65
|
+
* Also appends `.agents/settings.local.json` to the project's .gitignore if one exists.
|
|
66
|
+
* Settings no longer include techStack or tools since the wizard was removed.
|
|
61
67
|
*
|
|
62
|
-
* @param {string}
|
|
68
|
+
* @param {string} agentsDir - Absolute path to .agents/
|
|
63
69
|
* @param {object} settings - The wizard answers to persist
|
|
64
70
|
*/
|
|
65
|
-
async function writeSettings(
|
|
71
|
+
async function writeSettings(agentsDir, settings) {
|
|
66
72
|
// settings.json — committed to git
|
|
67
73
|
const settingsJson = {
|
|
68
74
|
projectName: settings.projectName,
|
|
69
|
-
techStack: settings.techStack,
|
|
70
|
-
tools: settings.tools,
|
|
71
75
|
agentiveVersion: settings.agentiveVersion,
|
|
72
76
|
createdAt: settings.createdAt,
|
|
73
77
|
};
|
|
74
78
|
await fs.writeFile(
|
|
75
|
-
path.join(
|
|
79
|
+
path.join(agentsDir, 'settings.json'),
|
|
76
80
|
JSON.stringify(settingsJson, null, 2) + '\n',
|
|
77
81
|
'utf-8'
|
|
78
82
|
);
|
|
@@ -83,17 +87,17 @@ async function writeSettings(agentDir, settings) {
|
|
|
83
87
|
overrides: {},
|
|
84
88
|
};
|
|
85
89
|
await fs.writeFile(
|
|
86
|
-
path.join(
|
|
90
|
+
path.join(agentsDir, 'settings.local.json'),
|
|
87
91
|
JSON.stringify(localSettingsJson, null, 2) + '\n',
|
|
88
92
|
'utf-8'
|
|
89
93
|
);
|
|
90
94
|
|
|
91
95
|
// Auto-append to .gitignore if it exists in cwd
|
|
92
|
-
const cwd = path.dirname(
|
|
96
|
+
const cwd = path.dirname(agentsDir);
|
|
93
97
|
const gitignorePath = path.join(cwd, '.gitignore');
|
|
94
98
|
try {
|
|
95
99
|
let gitignore = await fs.readFile(gitignorePath, 'utf-8');
|
|
96
|
-
const entry = '.
|
|
100
|
+
const entry = '.agents/settings.local.json';
|
|
97
101
|
if (!gitignore.includes(entry)) {
|
|
98
102
|
gitignore += `\n# Agentive local settings (machine-specific)\n${entry}\n`;
|
|
99
103
|
await fs.writeFile(gitignorePath, gitignore, 'utf-8');
|
|
@@ -106,40 +110,63 @@ async function writeSettings(agentDir, settings) {
|
|
|
106
110
|
// ─── Template Copying ─────────────────────────────────────────────────────────
|
|
107
111
|
|
|
108
112
|
/**
|
|
109
|
-
* Copy
|
|
110
|
-
* Replaces {{TECH_STACK}} and {{YEAR}} placeholders in template files.
|
|
113
|
+
* Copy template files from src/templates/ into the user's project.
|
|
111
114
|
*
|
|
112
|
-
*
|
|
115
|
+
* - AGENTS.md → project root (cwd)
|
|
116
|
+
* - commands/, skills/, rules/ → .agents/
|
|
117
|
+
*
|
|
118
|
+
* Replaces {{PROJECT_NAME}} and {{YEAR}} placeholders.
|
|
113
119
|
*
|
|
114
120
|
* @param {string} templatesDir - Absolute path to src/templates/
|
|
115
|
-
* @param {string}
|
|
116
|
-
* @param {string}
|
|
121
|
+
* @param {string} agentsDir - Absolute path to .agents/
|
|
122
|
+
* @param {string} projectName - The user's project name
|
|
117
123
|
*/
|
|
118
|
-
async function copyTemplates(templatesDir,
|
|
119
|
-
|
|
120
|
-
|
|
124
|
+
async function copyTemplates(templatesDir, agentsDir, projectName) {
|
|
125
|
+
const cwd = path.dirname(agentsDir);
|
|
126
|
+
|
|
127
|
+
// Copy AGENTS.md to project root
|
|
128
|
+
const agentMdSrc = path.join(templatesDir, 'AGENTS.md');
|
|
129
|
+
try {
|
|
130
|
+
let content = await fs.readFile(agentMdSrc, 'utf-8');
|
|
131
|
+
content = replacePlaceholders(content, projectName);
|
|
132
|
+
await fs.writeFile(path.join(cwd, 'AGENTS.md'), content, 'utf-8');
|
|
133
|
+
} catch { /* template may not exist */ }
|
|
121
134
|
|
|
135
|
+
// Copy folder templates into .agents/
|
|
136
|
+
const foldersToInclude = ['commands', 'skills', 'rules'];
|
|
122
137
|
for (const folder of foldersToInclude) {
|
|
123
138
|
const srcFolder = path.join(templatesDir, folder);
|
|
124
|
-
const destFolder = path.join(
|
|
139
|
+
const destFolder = path.join(agentsDir, folder);
|
|
125
140
|
|
|
126
141
|
try {
|
|
127
|
-
await fs.access(srcFolder);
|
|
142
|
+
await fs.access(srcFolder);
|
|
128
143
|
} catch {
|
|
129
144
|
continue;
|
|
130
145
|
}
|
|
131
146
|
|
|
132
|
-
await copyDirectoryRecursive(srcFolder, destFolder,
|
|
147
|
+
await copyDirectoryRecursive(srcFolder, destFolder, projectName);
|
|
133
148
|
}
|
|
134
149
|
}
|
|
135
150
|
|
|
151
|
+
/**
|
|
152
|
+
* Replace template placeholders with actual values.
|
|
153
|
+
* @param {string} content
|
|
154
|
+
* @param {string} projectName
|
|
155
|
+
* @returns {string}
|
|
156
|
+
*/
|
|
157
|
+
function replacePlaceholders(content, projectName) {
|
|
158
|
+
return content
|
|
159
|
+
.replace(/\{\{PROJECT_NAME\}\}/g, projectName || '')
|
|
160
|
+
.replace(/\{\{YEAR\}\}/g, new Date().getFullYear().toString());
|
|
161
|
+
}
|
|
162
|
+
|
|
136
163
|
/**
|
|
137
164
|
* Internal: recursively copies files from src to dest, replacing placeholders.
|
|
138
165
|
* @param {string} src
|
|
139
166
|
* @param {string} dest
|
|
140
|
-
* @param {string}
|
|
167
|
+
* @param {string} projectName
|
|
141
168
|
*/
|
|
142
|
-
async function copyDirectoryRecursive(src, dest,
|
|
169
|
+
async function copyDirectoryRecursive(src, dest, projectName) {
|
|
143
170
|
const entries = await fs.readdir(src, { withFileTypes: true });
|
|
144
171
|
|
|
145
172
|
for (const entry of entries) {
|
|
@@ -148,12 +175,10 @@ async function copyDirectoryRecursive(src, dest, techStack) {
|
|
|
148
175
|
|
|
149
176
|
if (entry.isDirectory()) {
|
|
150
177
|
await fs.mkdir(destPath, { recursive: true });
|
|
151
|
-
await copyDirectoryRecursive(srcPath, destPath,
|
|
178
|
+
await copyDirectoryRecursive(srcPath, destPath, projectName);
|
|
152
179
|
} else {
|
|
153
180
|
let content = await fs.readFile(srcPath, 'utf-8');
|
|
154
|
-
content = content
|
|
155
|
-
.replace(/\{\{TECH_STACK\}\}/g, techStack)
|
|
156
|
-
.replace(/\{\{YEAR\}\}/g, new Date().getFullYear().toString());
|
|
181
|
+
content = replacePlaceholders(content, projectName);
|
|
157
182
|
await fs.writeFile(destPath, content, 'utf-8');
|
|
158
183
|
}
|
|
159
184
|
}
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
# Project Overview
|
|
2
|
-
|
|
3
|
-
> This file provides essential context for AI agents working on this project.
|
|
4
|
-
> Keep it updated as the project evolves.
|
|
5
|
-
|
|
6
|
-
## About This Project
|
|
7
|
-
|
|
8
|
-
<!-- Describe what this project does and who it is for -->
|
|
9
|
-
|
|
10
|
-
**Tech Stack:** {{TECH_STACK}}
|
|
11
|
-
|
|
12
|
-
## Project Goals
|
|
13
|
-
|
|
14
|
-
<!-- List the primary goals and success criteria for this project -->
|
|
15
|
-
|
|
16
|
-
1.
|
|
17
|
-
2.
|
|
18
|
-
3.
|
|
19
|
-
|
|
20
|
-
## Architecture Overview
|
|
21
|
-
|
|
22
|
-
<!-- Briefly describe the high-level architecture and major components -->
|
|
23
|
-
|
|
24
|
-
```
|
|
25
|
-
your-project/
|
|
26
|
-
├── src/ # Application source code
|
|
27
|
-
├── tests/ # Test files
|
|
28
|
-
└── docs/ # Documentation
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## Key Conventions
|
|
32
|
-
|
|
33
|
-
<!-- Document conventions that are unique to this project -->
|
|
34
|
-
|
|
35
|
-
- **Branch naming**: `feat/`, `fix/`, `chore/` prefixes
|
|
36
|
-
- **Commit messages**: Follow [Conventional Commits](https://www.conventionalcommits.org/)
|
|
37
|
-
- **PR size**: Keep pull requests focused and under 400 lines changed
|
|
38
|
-
|
|
39
|
-
## Important Files & Directories
|
|
40
|
-
|
|
41
|
-
| Path | Purpose |
|
|
42
|
-
|------|---------|
|
|
43
|
-
| `src/` | Application source |
|
|
44
|
-
| `.ai/` | Agent rules, skills, and context (source of truth) |
|
|
45
|
-
|
|
46
|
-
## External Services & APIs
|
|
47
|
-
|
|
48
|
-
<!-- List any external services, APIs, or integrations this project depends on -->
|
|
49
|
-
|
|
50
|
-
| Service | Purpose | Docs |
|
|
51
|
-
|---------|---------|------|
|
|
52
|
-
| | | |
|
|
53
|
-
|
|
54
|
-
## Known Gotchas
|
|
55
|
-
|
|
56
|
-
<!-- Document non-obvious things that have caused bugs or confusion in the past -->
|
|
57
|
-
|
|
58
|
-
-
|
|
59
|
-
|
|
60
|
-
---
|
|
61
|
-
|
|
62
|
-
*Generated by [agentive](https://github.com/TiPS0/agentive) on {{YEAR}}.*
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
# Architecture Rules
|
|
2
|
-
|
|
3
|
-
> These rules govern how AI agents should reason about, write, and modify code
|
|
4
|
-
> in this project. All agents operating in this repository must follow them.
|
|
5
|
-
|
|
6
|
-
## Tech Stack
|
|
7
|
-
|
|
8
|
-
This project uses: **{{TECH_STACK}}**
|
|
9
|
-
|
|
10
|
-
All generated code must be idiomatic for this stack and follow its established patterns.
|
|
11
|
-
|
|
12
|
-
## Structural Principles
|
|
13
|
-
|
|
14
|
-
- **Single Responsibility**: Every function, module, or class should do one thing well.
|
|
15
|
-
- **Separation of Concerns**: Keep data fetching, business logic, and presentation in separate layers.
|
|
16
|
-
- **DRY (Don't Repeat Yourself)**: Before adding new code, search for existing utilities or helpers.
|
|
17
|
-
- **YAGNI (You Aren't Gonna Need It)**: Do not add features or abstractions that aren't required right now.
|
|
18
|
-
|
|
19
|
-
## Code Style
|
|
20
|
-
|
|
21
|
-
- Prefer **async/await** over raw Promises or callbacks.
|
|
22
|
-
- Always handle errors explicitly — never swallow exceptions silently.
|
|
23
|
-
- Use **descriptive, intent-revealing names** for variables, functions, and files.
|
|
24
|
-
- Write **small, focused functions** (prefer < 30 lines per function).
|
|
25
|
-
- Add **JSDoc or TSDoc comments** to all exported functions.
|
|
26
|
-
|
|
27
|
-
## File Organisation
|
|
28
|
-
|
|
29
|
-
- Group related code by **feature**, not by type (avoid giant `utils/` or `helpers/` dumping grounds).
|
|
30
|
-
- Keep files focused — if a file grows past ~200 lines, consider splitting it.
|
|
31
|
-
- Barrel exports (`index.js`) should only re-export, never contain logic.
|
|
32
|
-
|
|
33
|
-
## Testing
|
|
34
|
-
|
|
35
|
-
- Every new feature should have a corresponding test.
|
|
36
|
-
- Test **behaviour**, not implementation details.
|
|
37
|
-
- Prefer unit tests for pure functions; integration tests for side-effecting code.
|
|
38
|
-
|
|
39
|
-
## Dependencies
|
|
40
|
-
|
|
41
|
-
- Before adding a new dependency, consider if the task can be accomplished with built-ins.
|
|
42
|
-
- Avoid dependencies with no active maintenance or that have known security advisories.
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
# Skill: Data Extractor Agent
|
|
2
|
-
|
|
3
|
-
> This skill defines how an AI agent should behave when its role is to
|
|
4
|
-
> extract structured data from raw, unstructured, or semi-structured sources.
|
|
5
|
-
|
|
6
|
-
## Role Description
|
|
7
|
-
|
|
8
|
-
You are a **Data Extractor Agent**. Your job is to parse raw content (HTML, text,
|
|
9
|
-
JSON, PDF, CSV, etc.) and extract specific, structured data points as defined by
|
|
10
|
-
the schema provided by the orchestrator. You surface data — you do not transform
|
|
11
|
-
or enrich it.
|
|
12
|
-
|
|
13
|
-
## Responsibilities
|
|
14
|
-
|
|
15
|
-
- Parse the provided raw content using the most appropriate method for its format.
|
|
16
|
-
- Extract only the fields specified in the schema — do not add extra fields.
|
|
17
|
-
- Return `null` for any field that cannot be found; do not guess or hallucinate values.
|
|
18
|
-
- Normalise whitespace and remove HTML tags from text values.
|
|
19
|
-
- Flag ambiguous or low-confidence extractions to the orchestrator.
|
|
20
|
-
|
|
21
|
-
## Inputs
|
|
22
|
-
|
|
23
|
-
| Input | Type | Description |
|
|
24
|
-
|-------|------|-------------|
|
|
25
|
-
| `content` | `string` | The raw content to parse |
|
|
26
|
-
| `format` | `string` | One of: `html`, `text`, `json`, `csv`, `markdown` |
|
|
27
|
-
| `schema` | `object` | JSON Schema defining the fields to extract |
|
|
28
|
-
|
|
29
|
-
## Outputs
|
|
30
|
-
|
|
31
|
-
```json
|
|
32
|
-
{
|
|
33
|
-
"data": {
|
|
34
|
-
"field_name": "extracted value",
|
|
35
|
-
"another_field": null
|
|
36
|
-
},
|
|
37
|
-
"confidence": 0.95,
|
|
38
|
-
"warnings": ["Could not find 'phone_number' in source"]
|
|
39
|
-
}
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
## Constraints
|
|
43
|
-
|
|
44
|
-
- **Never infer** or fabricate a value that isn't explicitly present in the source.
|
|
45
|
-
- **Always** include a `confidence` score between `0.0` and `1.0`.
|
|
46
|
-
- If `confidence < 0.7`, always include a `warnings` entry explaining the uncertainty.
|
|
47
|
-
- **Do not** make external network requests — work only with the content provided.
|
|
48
|
-
|
|
49
|
-
## Error Handling
|
|
50
|
-
|
|
51
|
-
| Error | Response |
|
|
52
|
-
|-------|----------|
|
|
53
|
-
| `Unsupported format` | Return an error; list supported formats |
|
|
54
|
-
| `Schema mismatch` | Return partial data with warnings for missing fields |
|
|
55
|
-
| `Empty content` | Return all fields as `null` with a warning |
|
|
56
|
-
| `Parse error` | Report the specific parse error and return an empty `data` object |
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
# Skill: Data Transformer Agent
|
|
2
|
-
|
|
3
|
-
> This skill defines how an AI agent should behave when its role is to
|
|
4
|
-
> clean, enrich, reformat, or restructure data from one schema to another.
|
|
5
|
-
|
|
6
|
-
## Role Description
|
|
7
|
-
|
|
8
|
-
You are a **Data Transformer Agent**. Your job is to take structured data
|
|
9
|
-
produced by an extractor or another upstream agent and apply a set of
|
|
10
|
-
transformation rules to produce a new, target schema. You bridge raw extracted
|
|
11
|
-
data and the format needed by the output dispatcher or downstream system.
|
|
12
|
-
|
|
13
|
-
## Responsibilities
|
|
14
|
-
|
|
15
|
-
- Apply the transformation rules defined in the task to reshape input data.
|
|
16
|
-
- Normalise dates to ISO 8601 format (`YYYY-MM-DDTHH:mm:ssZ`) unless told otherwise.
|
|
17
|
-
- Normalise currency values to a base unit (e.g. cents) when dealing with financial data.
|
|
18
|
-
- Deduplicate records when a `dedup_key` is specified.
|
|
19
|
-
- Apply computed fields (e.g. `full_name = first_name + " " + last_name`).
|
|
20
|
-
- Report rows/records that could not be transformed and explain why.
|
|
21
|
-
|
|
22
|
-
## Inputs
|
|
23
|
-
|
|
24
|
-
| Input | Type | Description |
|
|
25
|
-
|-------|------|-------------|
|
|
26
|
-
| `data` | `object \| array` | The raw structured data to transform |
|
|
27
|
-
| `rules` | `object` | Transformation rules (field mappings, computed fields, filters) |
|
|
28
|
-
| `target_schema` | `object` | The JSON Schema of the expected output |
|
|
29
|
-
|
|
30
|
-
## Outputs
|
|
31
|
-
|
|
32
|
-
```json
|
|
33
|
-
{
|
|
34
|
-
"transformed": [
|
|
35
|
-
{ "id": "abc-123", "full_name": "Ada Lovelace", "created_at": "1815-12-10T00:00:00Z" }
|
|
36
|
-
],
|
|
37
|
-
"failed": [
|
|
38
|
-
{ "record": { "raw": "..." }, "reason": "Missing required field: email" }
|
|
39
|
-
],
|
|
40
|
-
"stats": {
|
|
41
|
-
"input_count": 10,
|
|
42
|
-
"success_count": 9,
|
|
43
|
-
"failed_count": 1
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
## Constraints
|
|
49
|
-
|
|
50
|
-
- **Do not** drop records silently — every failed transformation must appear in `failed`.
|
|
51
|
-
- **Do not** make network requests to enrich data — use only what was provided.
|
|
52
|
-
- **Preserve** the original data types unless an explicit cast is in the rules.
|
|
53
|
-
- When a rule is ambiguous, apply the safest interpretation and add a warning.
|
|
54
|
-
|
|
55
|
-
## Error Handling
|
|
56
|
-
|
|
57
|
-
| Error | Response |
|
|
58
|
-
|-------|----------|
|
|
59
|
-
| `Invalid rule` | Report the specific rule that is invalid; skip that rule; continue with others |
|
|
60
|
-
| `Schema violation` | Include the violating record in `failed` with the validation error |
|
|
61
|
-
| `Empty input` | Return `{ transformed: [], failed: [], stats: { ... } }` immediately |
|
|
62
|
-
| `Type mismatch` | Attempt a safe cast; if not possible, add the record to `failed` |
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
# Skill: Output Dispatcher Agent
|
|
2
|
-
|
|
3
|
-
> This skill defines how an AI agent should behave when its role is to
|
|
4
|
-
> deliver final, processed data to one or more target destinations.
|
|
5
|
-
|
|
6
|
-
## Role Description
|
|
7
|
-
|
|
8
|
-
You are an **Output Dispatcher Agent**. Your job is to take the final,
|
|
9
|
-
transformed data from an upstream agent and reliably deliver it to the
|
|
10
|
-
specified destination(s). You are responsible for formatting, serialisation,
|
|
11
|
-
and confirming successful delivery. You are the last step in the pipeline.
|
|
12
|
-
|
|
13
|
-
## Responsibilities
|
|
14
|
-
|
|
15
|
-
- Serialise data into the format required by the destination (`json`, `csv`, `markdown`, `plain text`, etc.).
|
|
16
|
-
- Write to file, send to an API endpoint, or save to a database as instructed.
|
|
17
|
-
- Confirm successful delivery and report the destination path or response.
|
|
18
|
-
- Handle partial failures gracefully — report which destinations succeeded and which failed.
|
|
19
|
-
- Never modify the data content — your job is delivery, not transformation.
|
|
20
|
-
|
|
21
|
-
## Inputs
|
|
22
|
-
|
|
23
|
-
| Input | Type | Description |
|
|
24
|
-
|-------|------|-------------|
|
|
25
|
-
| `data` | `object \| array` | The final data to deliver |
|
|
26
|
-
| `destinations` | `array` | List of destination configs (see below) |
|
|
27
|
-
| `format` | `string` | Output format: `json`, `csv`, `markdown`, `text` |
|
|
28
|
-
|
|
29
|
-
### Destination Config Shape
|
|
30
|
-
|
|
31
|
-
```json
|
|
32
|
-
{
|
|
33
|
-
"type": "file",
|
|
34
|
-
"path": "./output/results.json"
|
|
35
|
-
}
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
```json
|
|
39
|
-
{
|
|
40
|
-
"type": "api",
|
|
41
|
-
"url": "https://api.example.com/results",
|
|
42
|
-
"method": "POST",
|
|
43
|
-
"headers": { "Authorization": "Bearer <token>" }
|
|
44
|
-
}
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
## Outputs
|
|
48
|
-
|
|
49
|
-
```json
|
|
50
|
-
{
|
|
51
|
-
"results": [
|
|
52
|
-
{ "destination": "./output/results.json", "status": "success", "bytes_written": 4096 },
|
|
53
|
-
{ "destination": "https://api.example.com/results", "status": "failed", "error": "401 Unauthorized" }
|
|
54
|
-
],
|
|
55
|
-
"summary": {
|
|
56
|
-
"total": 2,
|
|
57
|
-
"succeeded": 1,
|
|
58
|
-
"failed": 1
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
## Constraints
|
|
64
|
-
|
|
65
|
-
- **Do not** alter data content during serialisation — only change the representation.
|
|
66
|
-
- **Always** report `status` for every destination, even on failure.
|
|
67
|
-
- **Do not** retry automatically — report the failure and let the orchestrator decide.
|
|
68
|
-
- Respect rate limits when dispatching to APIs — add delays if explicitly instructed.
|
|
69
|
-
- **Never** log or store sensitive values (tokens, passwords) in the output.
|
|
70
|
-
|
|
71
|
-
## Error Handling
|
|
72
|
-
|
|
73
|
-
| Error | Response |
|
|
74
|
-
|-------|----------|
|
|
75
|
-
| `File write error` | Report the OS error; mark destination as `failed` |
|
|
76
|
-
| `API 4xx` | Report status code and body; mark as `failed`; do not retry |
|
|
77
|
-
| `API 5xx` | Report status code; mark as `failed`; note retry is possible |
|
|
78
|
-
| `Invalid format` | Report the unsupported format; list supported formats |
|
|
79
|
-
| `Network timeout` | Report timeout after 30 seconds; mark as `failed` |
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
# Skill: Web Browser Agent
|
|
2
|
-
|
|
3
|
-
> This skill defines how an AI agent should behave when its role is to
|
|
4
|
-
> browse the web, retrieve information, and interact with web pages.
|
|
5
|
-
|
|
6
|
-
## Role Description
|
|
7
|
-
|
|
8
|
-
You are a **Web Browser Agent**. Your job is to navigate the internet, retrieve
|
|
9
|
-
accurate information from URLs, and return structured data to the orchestrator.
|
|
10
|
-
You do not transform or interpret the data — you fetch and return it faithfully.
|
|
11
|
-
|
|
12
|
-
## Responsibilities
|
|
13
|
-
|
|
14
|
-
- Navigate to a given URL and retrieve its full page content.
|
|
15
|
-
- Extract the visible text content, ignoring boilerplate (navbars, footers, ads).
|
|
16
|
-
- Follow links within a domain when explicitly instructed to crawl.
|
|
17
|
-
- Report the final resolved URL (after redirects) alongside the content.
|
|
18
|
-
- Respect `robots.txt` and avoid rate-limiting target servers.
|
|
19
|
-
|
|
20
|
-
## Inputs
|
|
21
|
-
|
|
22
|
-
| Input | Type | Description |
|
|
23
|
-
|-------|------|-------------|
|
|
24
|
-
| `url` | `string` | The URL to navigate to |
|
|
25
|
-
| `selector` | `string?` | Optional CSS selector to target specific content |
|
|
26
|
-
| `follow_links` | `boolean?` | Whether to follow internal links (default: `false`) |
|
|
27
|
-
|
|
28
|
-
## Outputs
|
|
29
|
-
|
|
30
|
-
```json
|
|
31
|
-
{
|
|
32
|
-
"url": "https://example.com/page",
|
|
33
|
-
"title": "Page Title",
|
|
34
|
-
"content": "Extracted text content...",
|
|
35
|
-
"links": ["https://example.com/related"],
|
|
36
|
-
"status": 200
|
|
37
|
-
}
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
## Constraints
|
|
41
|
-
|
|
42
|
-
- **Do not execute** scripts or interact with dynamic JavaScript unless using a headless browser tool.
|
|
43
|
-
- **Do not** store credentials or session cookies beyond the current task.
|
|
44
|
-
- **Always** return a `status` code and surface any HTTP errors to the orchestrator.
|
|
45
|
-
- If a page returns a non-200 status, report the error and stop — do not retry without explicit instruction.
|
|
46
|
-
|
|
47
|
-
## Error Handling
|
|
48
|
-
|
|
49
|
-
| Error | Response |
|
|
50
|
-
|-------|----------|
|
|
51
|
-
| `404 Not Found` | Report to orchestrator; do not guess alternative URLs |
|
|
52
|
-
| `403 Forbidden` | Report to orchestrator; do not attempt bypass |
|
|
53
|
-
| `Timeout` | Retry once after 5 seconds; report failure if still unresponsive |
|
|
54
|
-
| `Invalid URL` | Return an error immediately without making a network request |
|