aioengine 0.1.1 → 0.1.3
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 +36 -15
- package/package.json +1 -1
- package/src/index.js +64 -15
package/README.md
CHANGED
|
@@ -4,14 +4,35 @@ AI change control for developers using Claude Code, Cursor, Codex, Copilot, and
|
|
|
4
4
|
|
|
5
5
|
aioengine helps you review AI-generated code before you trust it. It scans your repo for missing guardrails, checks changed files for risky edits, and flags when AI may have wandered outside the requested task.
|
|
6
6
|
|
|
7
|
+
## Quick start
|
|
8
|
+
|
|
9
|
+
Run aioengine in any JavaScript or TypeScript project:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npx aioengine check
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Then set up AI coding guardrails:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npx aioengine init
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
After your AI coding tool makes changes, review them before committing:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npx aioengine scope "update landing page headline"
|
|
25
|
+
npx aioengine review
|
|
26
|
+
```
|
|
27
|
+
|
|
7
28
|
## Commands
|
|
8
29
|
|
|
9
30
|
```bash
|
|
10
|
-
aioengine init
|
|
11
|
-
aioengine check
|
|
12
|
-
aioengine scope "add init command"
|
|
13
|
-
aioengine review
|
|
14
|
-
aioengine rules
|
|
31
|
+
npx aioengine init
|
|
32
|
+
npx aioengine check
|
|
33
|
+
npx aioengine scope "add init command"
|
|
34
|
+
npx aioengine review
|
|
35
|
+
npx aioengine rules
|
|
15
36
|
```
|
|
16
37
|
|
|
17
38
|
## Why aioengine exists
|
|
@@ -43,7 +64,7 @@ CLAUDE.md
|
|
|
43
64
|
Run:
|
|
44
65
|
|
|
45
66
|
```bash
|
|
46
|
-
aioengine init
|
|
67
|
+
npx aioengine init
|
|
47
68
|
```
|
|
48
69
|
|
|
49
70
|
## `aioengine check`
|
|
@@ -66,7 +87,7 @@ Checks for:
|
|
|
66
87
|
Run:
|
|
67
88
|
|
|
68
89
|
```bash
|
|
69
|
-
aioengine check
|
|
90
|
+
npx aioengine check
|
|
70
91
|
```
|
|
71
92
|
|
|
72
93
|
## `aioengine scope`
|
|
@@ -76,10 +97,10 @@ Checks whether changed files match the task you gave your AI coding tool.
|
|
|
76
97
|
Example:
|
|
77
98
|
|
|
78
99
|
```bash
|
|
79
|
-
aioengine scope "update landing page headline"
|
|
100
|
+
npx aioengine scope "update landing page headline"
|
|
80
101
|
```
|
|
81
102
|
|
|
82
|
-
If the task sounds like a UI change but AI modified billing, database, env, dependency, or deployment files, aioengine will flag possible scope drift.
|
|
103
|
+
If the task sounds like a UI change but AI modified billing, database, env, dependency, CLI, or deployment files, aioengine will flag possible scope drift.
|
|
83
104
|
|
|
84
105
|
## `aioengine review`
|
|
85
106
|
|
|
@@ -88,7 +109,7 @@ Reviews current uncommitted changes for risky files.
|
|
|
88
109
|
Run:
|
|
89
110
|
|
|
90
111
|
```bash
|
|
91
|
-
aioengine review
|
|
112
|
+
npx aioengine review
|
|
92
113
|
```
|
|
93
114
|
|
|
94
115
|
aioengine will flag changes to files that often deserve extra review, such as:
|
|
@@ -108,7 +129,7 @@ Generates starter AI coding rules for Claude Code and Cursor.
|
|
|
108
129
|
Run:
|
|
109
130
|
|
|
110
131
|
```bash
|
|
111
|
-
aioengine rules
|
|
132
|
+
npx aioengine rules
|
|
112
133
|
```
|
|
113
134
|
|
|
114
135
|
This creates or skips:
|
|
@@ -121,13 +142,13 @@ CLAUDE.md
|
|
|
121
142
|
## Example workflow
|
|
122
143
|
|
|
123
144
|
```bash
|
|
124
|
-
aioengine init
|
|
125
|
-
aioengine check
|
|
145
|
+
npx aioengine init
|
|
146
|
+
npx aioengine check
|
|
126
147
|
|
|
127
148
|
# Ask Claude, Cursor, Codex, or another AI coding tool to make a change.
|
|
128
149
|
|
|
129
|
-
aioengine scope "update landing page headline"
|
|
130
|
-
aioengine review
|
|
150
|
+
npx aioengine scope "update landing page headline"
|
|
151
|
+
npx aioengine review
|
|
131
152
|
```
|
|
132
153
|
|
|
133
154
|
## Current status
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -5,13 +5,14 @@ import pc from "picocolors";
|
|
|
5
5
|
import fs from "node:fs";
|
|
6
6
|
import path from "node:path";
|
|
7
7
|
import { execSync } from "node:child_process";
|
|
8
|
+
import { fileURLToPath } from "node:url";
|
|
8
9
|
|
|
9
10
|
const program = new Command();
|
|
10
11
|
|
|
11
12
|
program
|
|
12
13
|
.name("aioengine")
|
|
13
14
|
.description("AI change control for developers using AI coding tools.")
|
|
14
|
-
.version(
|
|
15
|
+
.version(getCliVersion());
|
|
15
16
|
|
|
16
17
|
program
|
|
17
18
|
.command("init")
|
|
@@ -61,7 +62,6 @@ function runInit() {
|
|
|
61
62
|
|
|
62
63
|
const aioengineDir = ".aioengine";
|
|
63
64
|
const configPath = path.join(aioengineDir, "config.json");
|
|
64
|
-
const claudePath = "CLAUDE.md";
|
|
65
65
|
const cursorDir = ".cursor/rules";
|
|
66
66
|
const cursorPath = path.join(cursorDir, "aioengine.mdc");
|
|
67
67
|
|
|
@@ -91,12 +91,7 @@ function runInit() {
|
|
|
91
91
|
skipped.push(configPath);
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
|
|
95
|
-
fs.writeFileSync(path.join(root, claudePath), getClaudeRules());
|
|
96
|
-
created.push(claudePath);
|
|
97
|
-
} else {
|
|
98
|
-
skipped.push(claudePath);
|
|
99
|
-
}
|
|
94
|
+
createClaudeRulesSafely(root, created, skipped);
|
|
100
95
|
|
|
101
96
|
if (!exists(cursorDir, root)) {
|
|
102
97
|
fs.mkdirSync(path.join(root, cursorDir), { recursive: true });
|
|
@@ -112,6 +107,14 @@ function runInit() {
|
|
|
112
107
|
printSection("Created", created, "green");
|
|
113
108
|
printSection("Skipped", skipped, "yellow");
|
|
114
109
|
|
|
110
|
+
if (skipped.includes("CLAUDE.md already exists")) {
|
|
111
|
+
console.log(
|
|
112
|
+
`\n${pc.dim(
|
|
113
|
+
"aioengine did not modify your existing CLAUDE.md. Suggested Claude rules were saved to .aioengine/suggested-claude-rules.md if that file did not already exist."
|
|
114
|
+
)}`
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
115
118
|
console.log(pc.bold("Next steps:"));
|
|
116
119
|
console.log(` 1. Run ${pc.cyan("aioengine check")}`);
|
|
117
120
|
console.log(` 2. Make or review AI-generated changes`);
|
|
@@ -381,19 +384,13 @@ function runRules() {
|
|
|
381
384
|
|
|
382
385
|
const root = getProjectRoot();
|
|
383
386
|
|
|
384
|
-
const claudePath = "CLAUDE.md";
|
|
385
387
|
const cursorDir = ".cursor/rules";
|
|
386
388
|
const cursorPath = path.join(cursorDir, "aioengine.mdc");
|
|
387
389
|
|
|
388
390
|
const created = [];
|
|
389
391
|
const skipped = [];
|
|
390
392
|
|
|
391
|
-
|
|
392
|
-
fs.writeFileSync(path.join(root, claudePath), getClaudeRules());
|
|
393
|
-
created.push(claudePath);
|
|
394
|
-
} else {
|
|
395
|
-
skipped.push(claudePath);
|
|
396
|
-
}
|
|
393
|
+
createClaudeRulesSafely(root, created, skipped);
|
|
397
394
|
|
|
398
395
|
if (!exists(cursorDir, root)) {
|
|
399
396
|
fs.mkdirSync(path.join(root, cursorDir), { recursive: true });
|
|
@@ -409,6 +406,14 @@ function runRules() {
|
|
|
409
406
|
printSection("Created", created, "green");
|
|
410
407
|
printSection("Skipped", skipped, "yellow");
|
|
411
408
|
|
|
409
|
+
if (skipped.includes("CLAUDE.md already exists")) {
|
|
410
|
+
console.log(
|
|
411
|
+
`\n${pc.dim(
|
|
412
|
+
"aioengine did not modify your existing CLAUDE.md. Suggested Claude rules were saved to .aioengine/suggested-claude-rules.md if that file did not already exist."
|
|
413
|
+
)}`
|
|
414
|
+
);
|
|
415
|
+
}
|
|
416
|
+
|
|
412
417
|
console.log(pc.bold("Next step:"));
|
|
413
418
|
console.log(` Run ${pc.cyan("aioengine check")} again.`);
|
|
414
419
|
}
|
|
@@ -838,6 +843,37 @@ function getDefaultConfig() {
|
|
|
838
843
|
};
|
|
839
844
|
}
|
|
840
845
|
|
|
846
|
+
function createClaudeRulesSafely(root, created, skipped) {
|
|
847
|
+
const claudePath = path.join(root, "CLAUDE.md");
|
|
848
|
+
const aioengineDir = path.join(root, ".aioengine");
|
|
849
|
+
const suggestedPath = path.join(
|
|
850
|
+
root,
|
|
851
|
+
".aioengine",
|
|
852
|
+
"suggested-claude-rules.md"
|
|
853
|
+
);
|
|
854
|
+
|
|
855
|
+
if (!fs.existsSync(aioengineDir)) {
|
|
856
|
+
fs.mkdirSync(aioengineDir, { recursive: true });
|
|
857
|
+
created.push(".aioengine");
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
if (!fs.existsSync(claudePath)) {
|
|
861
|
+
fs.writeFileSync(claudePath, getClaudeRules(), "utf8");
|
|
862
|
+
created.push("CLAUDE.md");
|
|
863
|
+
return;
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
skipped.push("CLAUDE.md already exists");
|
|
867
|
+
|
|
868
|
+
if (!fs.existsSync(suggestedPath)) {
|
|
869
|
+
fs.writeFileSync(suggestedPath, getClaudeRules(), "utf8");
|
|
870
|
+
created.push(".aioengine/suggested-claude-rules.md");
|
|
871
|
+
return;
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
skipped.push(".aioengine/suggested-claude-rules.md already exists");
|
|
875
|
+
}
|
|
876
|
+
|
|
841
877
|
function getClaudeRules() {
|
|
842
878
|
return `# AI Coding Rules
|
|
843
879
|
|
|
@@ -894,4 +930,17 @@ Do not add dependencies without a clear reason.
|
|
|
894
930
|
|
|
895
931
|
For UI-only tasks, avoid backend, API, database, and config changes.
|
|
896
932
|
`;
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
function getCliVersion() {
|
|
936
|
+
try {
|
|
937
|
+
const currentFile = fileURLToPath(import.meta.url);
|
|
938
|
+
const currentDir = path.dirname(currentFile);
|
|
939
|
+
const packagePath = path.join(currentDir, "..", "package.json");
|
|
940
|
+
const packageJson = JSON.parse(fs.readFileSync(packagePath, "utf8"));
|
|
941
|
+
|
|
942
|
+
return packageJson.version ?? "0.0.0";
|
|
943
|
+
} catch {
|
|
944
|
+
return "0.0.0";
|
|
945
|
+
}
|
|
897
946
|
}
|