carto-md 1.0.15 → 1.0.17
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/CONTRIBUTING.md +4 -4
- package/README.md +3 -1
- package/package.json +1 -1
- package/src/cli/index.js +3 -0
- package/src/cli/remove.js +37 -0
- package/src/cli/sync.js +2 -0
- package/src/cli/update-check.js +48 -0
- package/src/cli/watch.js +2 -0
package/CONTRIBUTING.md
CHANGED
|
@@ -33,7 +33,7 @@ Wanted: Django, Rails, Laravel, NestJS, Hono, Gin, Spring.
|
|
|
33
33
|
|
|
34
34
|
## How to add a language
|
|
35
35
|
|
|
36
|
-
1. Create `src/
|
|
36
|
+
1. Create `src/extractors/languages/yourlanguage.js`
|
|
37
37
|
2. Export a single function: `extractFromFile(filePath, fileContent)`
|
|
38
38
|
3. Return:
|
|
39
39
|
```js
|
|
@@ -44,7 +44,7 @@ Wanted: Django, Rails, Laravel, NestJS, Hono, Gin, Spring.
|
|
|
44
44
|
exports: [{ name }]
|
|
45
45
|
}
|
|
46
46
|
```
|
|
47
|
-
4. Add it to `src/
|
|
47
|
+
4. Add it to `src/extractors/loader.js` language map
|
|
48
48
|
5. Test on at least 3 real open-source projects
|
|
49
49
|
6. Open a PR with before/after AGENTS.md examples
|
|
50
50
|
|
|
@@ -80,7 +80,7 @@ Wanted: Django, Rails, Laravel, NestJS, Hono, Gin, Spring.
|
|
|
80
80
|
## Development setup
|
|
81
81
|
|
|
82
82
|
```bash
|
|
83
|
-
git clone https://github.com/
|
|
83
|
+
git clone https://github.com/theanshsonkar/carto
|
|
84
84
|
cd carto-ansh
|
|
85
85
|
npm install
|
|
86
86
|
node src/cli/index.js init # test in any project
|
|
@@ -95,7 +95,7 @@ node src/cli/index.js init # test in any project
|
|
|
95
95
|
- [ ] No changes to merger logic (unless explicitly fixing a merger bug)
|
|
96
96
|
- [ ] No network calls added
|
|
97
97
|
- [ ] `carto --version` still works
|
|
98
|
-
- [ ]
|
|
98
|
+
- [ ] `npm test` passes
|
|
99
99
|
|
|
100
100
|
---
|
|
101
101
|
|
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
[](LICENSE)
|
|
5
5
|
[](https://www.npmjs.com/package/carto-md)
|
|
6
6
|
|
|
7
|
-
**Your code changes. AGENTS.md updates. Every AI always knows.**
|
|
7
|
+
**Maps your codebase so AI stops guessing. Your code changes. AGENTS.md updates. Every AI always knows.**
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
10
|
npm install -g carto-md
|
|
@@ -52,6 +52,8 @@ Same task, two Claude sessions: *"Add a `notes` field to the booking model."*
|
|
|
52
52
|
|
|
53
53
|
Not smarter AI. The same AI with accurate facts.
|
|
54
54
|
|
|
55
|
+
*Stress tested on cal.com (5,018 files): 87% route coverage, 100% model field accuracy, import graph with zero phantom links.*
|
|
56
|
+
|
|
55
57
|
---
|
|
56
58
|
|
|
57
59
|
## Know what breaks before you break it
|
package/package.json
CHANGED
package/src/cli/index.js
CHANGED
|
@@ -12,6 +12,7 @@ Commands:
|
|
|
12
12
|
watch Read .carto/config.json, start file watcher
|
|
13
13
|
sync Read .carto/config.json, run one sync, exit
|
|
14
14
|
impact <file> Show which files and routes are affected by changing a file
|
|
15
|
+
remove Remove AGENTS.md and .carto/ from this project
|
|
15
16
|
|
|
16
17
|
Options:
|
|
17
18
|
--help, -h Show this help message
|
|
@@ -46,6 +47,8 @@ if (command === 'init') {
|
|
|
46
47
|
} else if (command === 'impact') {
|
|
47
48
|
const fileArg = process.argv[3];
|
|
48
49
|
require('./impact').run(process.cwd(), fileArg);
|
|
50
|
+
} else if (command === 'remove') {
|
|
51
|
+
require('./remove').run(process.cwd());
|
|
49
52
|
} else {
|
|
50
53
|
console.error(`[CARTO] Unknown command: ${command}`);
|
|
51
54
|
printUsage();
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
function run(projectRoot) {
|
|
5
|
+
const agentsPath = path.join(projectRoot, 'AGENTS.md');
|
|
6
|
+
const cartoDir = path.join(projectRoot, '.carto');
|
|
7
|
+
|
|
8
|
+
const agentsExists = fs.existsSync(agentsPath);
|
|
9
|
+
const cartoDirExists = fs.existsSync(cartoDir);
|
|
10
|
+
|
|
11
|
+
if (!agentsExists && !cartoDirExists) {
|
|
12
|
+
console.log('[CARTO] Nothing to remove — Carto is not initialized in this project.');
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (agentsExists) {
|
|
17
|
+
try {
|
|
18
|
+
fs.unlinkSync(agentsPath);
|
|
19
|
+
console.log('[CARTO] Removed AGENTS.md');
|
|
20
|
+
} catch (err) {
|
|
21
|
+
console.error(`[CARTO] Failed to remove AGENTS.md: ${err.message}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (cartoDirExists) {
|
|
26
|
+
try {
|
|
27
|
+
fs.rmSync(cartoDir, { recursive: true, force: true });
|
|
28
|
+
console.log('[CARTO] Removed .carto/');
|
|
29
|
+
} catch (err) {
|
|
30
|
+
console.error(`[CARTO] Failed to remove .carto/: ${err.message}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
console.log('[CARTO] Carto removed from this project.');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
module.exports = { run };
|
package/src/cli/sync.js
CHANGED
|
@@ -2,8 +2,10 @@ const fs = require('fs');
|
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const { runFullSync } = require('../sync');
|
|
4
4
|
const { resolveConfig } = require('./init');
|
|
5
|
+
const { checkForUpdate } = require('./update-check');
|
|
5
6
|
|
|
6
7
|
async function run(projectRoot) {
|
|
8
|
+
checkForUpdate(); // fire and forget
|
|
7
9
|
const configPath = path.join(projectRoot, '.carto', 'config.json');
|
|
8
10
|
|
|
9
11
|
if (!fs.existsSync(configPath)) {
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const https = require('https');
|
|
2
|
+
const pkg = require('../../package.json');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Fire-and-forget version check against the npm registry.
|
|
6
|
+
* Prints a one-liner to stderr if a newer version exists.
|
|
7
|
+
* Never throws, never blocks — safe to call without await.
|
|
8
|
+
*/
|
|
9
|
+
function checkForUpdate() {
|
|
10
|
+
const req = https.get('https://registry.npmjs.org/carto-md/latest', {
|
|
11
|
+
timeout: 3000,
|
|
12
|
+
}, (res) => {
|
|
13
|
+
let body = '';
|
|
14
|
+
res.on('data', (chunk) => { body += chunk; });
|
|
15
|
+
res.on('end', () => {
|
|
16
|
+
try {
|
|
17
|
+
const data = JSON.parse(body);
|
|
18
|
+
const latest = data.version;
|
|
19
|
+
if (latest && latest !== pkg.version && isNewer(latest, pkg.version)) {
|
|
20
|
+
process.stderr.write(
|
|
21
|
+
`[CARTO] Update available: ${pkg.version} → ${latest} | npm install -g carto-md\n`
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
} catch (_) {
|
|
25
|
+
// malformed JSON — ignore
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
req.on('timeout', () => { req.destroy(); });
|
|
31
|
+
req.on('error', () => { /* offline / DNS failure — ignore */ });
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Returns true if `a` is a newer semver than `b`.
|
|
36
|
+
* Only handles numeric major.minor.patch — good enough for this use case.
|
|
37
|
+
*/
|
|
38
|
+
function isNewer(a, b) {
|
|
39
|
+
const pa = a.split('.').map(Number);
|
|
40
|
+
const pb = b.split('.').map(Number);
|
|
41
|
+
for (let i = 0; i < 3; i++) {
|
|
42
|
+
if ((pa[i] || 0) > (pb[i] || 0)) return true;
|
|
43
|
+
if ((pa[i] || 0) < (pb[i] || 0)) return false;
|
|
44
|
+
}
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
module.exports = { checkForUpdate };
|
package/src/cli/watch.js
CHANGED
|
@@ -3,8 +3,10 @@ const path = require('path');
|
|
|
3
3
|
const { startWatcher } = require('../watcher/watch');
|
|
4
4
|
const { runFullSync } = require('../sync');
|
|
5
5
|
const { resolveConfig } = require('./init');
|
|
6
|
+
const { checkForUpdate } = require('./update-check');
|
|
6
7
|
|
|
7
8
|
async function run(projectRoot) {
|
|
9
|
+
checkForUpdate(); // fire and forget
|
|
8
10
|
const configPath = path.join(projectRoot, '.carto', 'config.json');
|
|
9
11
|
|
|
10
12
|
if (!fs.existsSync(configPath)) {
|