activate-agentmd 2.4.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/README.md +158 -0
- package/bin/agentmd.js +186 -0
- package/package.json +55 -0
- package/src/commands/agents.js +44 -0
- package/src/commands/analytics.js +128 -0
- package/src/commands/auth.js +144 -0
- package/src/commands/ci.js +296 -0
- package/src/commands/extract.js +254 -0
- package/src/commands/info.js +105 -0
- package/src/commands/init.js +166 -0
- package/src/commands/install.js +216 -0
- package/src/commands/link.js +206 -0
- package/src/commands/list.js +99 -0
- package/src/commands/outdated.js +92 -0
- package/src/commands/remove.js +72 -0
- package/src/commands/review.js +293 -0
- package/src/commands/search.js +110 -0
- package/src/commands/sync.js +245 -0
- package/src/commands/telemetry.js +82 -0
- package/src/commands/test.js +226 -0
- package/src/commands/update.js +115 -0
- package/src/commands/validate.js +125 -0
- package/src/config/license-public-keys.json +17 -0
- package/src/detect.json +452 -0
- package/src/lib/agents.js +301 -0
- package/src/lib/analytics.js +137 -0
- package/src/lib/coordinates.js +103 -0
- package/src/lib/credentials.js +115 -0
- package/src/lib/detect.js +352 -0
- package/src/lib/diff.js +142 -0
- package/src/lib/enterprise.js +140 -0
- package/src/lib/fetcher.js +174 -0
- package/src/lib/invocation.js +47 -0
- package/src/lib/license.js +234 -0
- package/src/lib/manifest.js +191 -0
- package/src/lib/patterns.js +135 -0
- package/src/lib/pro.js +149 -0
- package/src/lib/ranking.js +287 -0
- package/src/lib/registry.js +207 -0
- package/src/lib/star.js +105 -0
- package/src/lib/status.js +75 -0
- package/src/lib/telemetry.js +169 -0
- package/src/lib/versions.js +190 -0
- package/src/registry.json +33907 -0
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* versions.js
|
|
3
|
+
*
|
|
4
|
+
* Version pins: the antidote to training-data cutoffs.
|
|
5
|
+
*
|
|
6
|
+
* A model's weights remember the API that was current when it was trained —
|
|
7
|
+
* Pydantic's `.dict()`, Next.js's synchronous `params`, Tailwind's config
|
|
8
|
+
* file. The project's manifests know which major it actually runs. This
|
|
9
|
+
* module reads those majors and turns them into short, explicit rules that
|
|
10
|
+
* `link` writes next to the standards, so the agent is told "this is v2, the
|
|
11
|
+
* v1 methods are gone" before it writes a line.
|
|
12
|
+
*
|
|
13
|
+
* Each entry is hand-written and version-specific on purpose: a wrong pin is
|
|
14
|
+
* worse than none, so only the breaking differences a model routinely gets
|
|
15
|
+
* wrong are listed.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
"use strict";
|
|
19
|
+
|
|
20
|
+
const fs = require("fs");
|
|
21
|
+
const path = require("path");
|
|
22
|
+
|
|
23
|
+
/** lib -> major -> rules. Keys are npm names, PyPI names, or "go" / "python". */
|
|
24
|
+
const PINS = {
|
|
25
|
+
next: {
|
|
26
|
+
label: "Next.js",
|
|
27
|
+
13: ["App Router (`app/`) exists but `pages/` is still common; check which this project uses before adding routes."],
|
|
28
|
+
14: ["App Router with Server Actions (stable). Navigate with `next/navigation`, not `next/router`, inside `app/`."],
|
|
29
|
+
15: [
|
|
30
|
+
"Request APIs are async: `await params`, `await searchParams`, `await cookies()`, `await headers()` — synchronous access is deprecated.",
|
|
31
|
+
"`fetch` is no longer cached by default; opt in with `cache: 'force-cache'` or `revalidate`.",
|
|
32
|
+
"Ships React 19: `ref` is a prop, `use()` and `useActionState` are available.",
|
|
33
|
+
],
|
|
34
|
+
16: [
|
|
35
|
+
"Turbopack is the default bundler; do not add webpack-only config without checking it is still needed.",
|
|
36
|
+
"Request APIs are async only — `params`, `searchParams`, `cookies()`, `headers()` must be awaited; synchronous access was removed.",
|
|
37
|
+
"`middleware.ts` is `proxy.ts`; the old filename is not picked up.",
|
|
38
|
+
"Ships React 19: `ref` is a prop, `use()` and `useActionState` are available.",
|
|
39
|
+
],
|
|
40
|
+
},
|
|
41
|
+
react: {
|
|
42
|
+
label: "React",
|
|
43
|
+
18: ["Mount with `createRoot` (not `ReactDOM.render`). Effects double-invoke in StrictMode during development — write them idempotently."],
|
|
44
|
+
19: [
|
|
45
|
+
"`ref` is a regular prop on function components — do not use `forwardRef`.",
|
|
46
|
+
"Use `use()` to read promises/context, `useActionState` and `useFormStatus` for forms; Actions can be passed to `<form action>`.",
|
|
47
|
+
"`propTypes` and `defaultProps` on function components are ignored; use TypeScript and default parameters.",
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
pydantic: {
|
|
51
|
+
label: "Pydantic",
|
|
52
|
+
1: ["Pydantic v1 API: `.dict()`, `.json()`, `@validator`, `class Config`. Do not use v2 names (`model_dump`, `field_validator`)."],
|
|
53
|
+
2: [
|
|
54
|
+
"Use `.model_dump()` / `.model_dump_json()` / `.model_validate()` — `.dict()`, `.json()`, `.parse_obj()` are deprecated v1 names.",
|
|
55
|
+
"Validators are `@field_validator` and `@model_validator`; `@validator` and `@root_validator` are deprecated.",
|
|
56
|
+
"Configure with `model_config = ConfigDict(...)`, not an inner `class Config`. Use `TypeAdapter` for non-model types.",
|
|
57
|
+
],
|
|
58
|
+
},
|
|
59
|
+
sqlalchemy: {
|
|
60
|
+
label: "SQLAlchemy",
|
|
61
|
+
2: [
|
|
62
|
+
"Use 2.0 style: `select()` with `session.execute()` / `session.scalars()`; `session.query()` is legacy.",
|
|
63
|
+
"Declare models with `DeclarativeBase`, `Mapped[...]` and `mapped_column()`; `declarative_base()` and `Column` are legacy.",
|
|
64
|
+
],
|
|
65
|
+
},
|
|
66
|
+
django: {
|
|
67
|
+
label: "Django",
|
|
68
|
+
5: ["Django 5: `db_default` and `GeneratedField` exist; `USE_L10N` was removed; async ORM methods (`aget`, `acreate`, `afirst`) are available."],
|
|
69
|
+
},
|
|
70
|
+
prisma: {
|
|
71
|
+
label: "Prisma",
|
|
72
|
+
5: ["Prisma 5: `prisma.$extends` for extensions; `@prisma/client` generated in `node_modules` — run `prisma generate` after schema changes."],
|
|
73
|
+
6: ["Prisma 6: same API as 5; `omit` in queries is stable. Run `prisma generate` after schema changes."],
|
|
74
|
+
7: [
|
|
75
|
+
"Prisma 7 has no Rust query engine by default: instantiate the client with a driver adapter (for example `@prisma/adapter-pg`), not a bare `new PrismaClient()`.",
|
|
76
|
+
"Connection config lives in `prisma.config.ts`, not in the schema's `datasource url`.",
|
|
77
|
+
],
|
|
78
|
+
},
|
|
79
|
+
tailwindcss: {
|
|
80
|
+
label: "Tailwind CSS",
|
|
81
|
+
3: ["Tailwind v3: `tailwind.config.js` with `content` globs, `@tailwind base/components/utilities` in CSS."],
|
|
82
|
+
4: [
|
|
83
|
+
"Tailwind v4 is CSS-first: `@import \"tailwindcss\"`, design tokens in `@theme`, `@custom-variant` — there is no `tailwind.config.js` unless the project added `@config`.",
|
|
84
|
+
"`@apply` in a separate CSS file needs `@reference`. Renamed utilities: `shadow-sm`→`shadow-xs`, `outline-none`→`outline-hidden`, `ring`→`ring-3`, `rounded-sm`→`rounded-xs`.",
|
|
85
|
+
],
|
|
86
|
+
},
|
|
87
|
+
express: {
|
|
88
|
+
label: "Express",
|
|
89
|
+
5: [
|
|
90
|
+
"Express 5: rejected promises from async handlers reach error middleware automatically — no `next(err)` wrappers needed.",
|
|
91
|
+
"`req.query` is a read-only getter; route syntax is path-to-regexp v8 (`/{*splat}` instead of `*`, optional segments with `{}`); `res.redirect('back')` is gone.",
|
|
92
|
+
],
|
|
93
|
+
},
|
|
94
|
+
zod: {
|
|
95
|
+
label: "Zod",
|
|
96
|
+
4: [
|
|
97
|
+
"Zod 4: use top-level formats `z.email()`, `z.uuid()`, `z.url()` — `z.string().email()` is deprecated.",
|
|
98
|
+
"Error details are `.issues` (not `.errors`); the `message` option is `error`; use `z.strictObject` / `z.looseObject` instead of `.strict()` / `.passthrough()`.",
|
|
99
|
+
],
|
|
100
|
+
},
|
|
101
|
+
eslint: {
|
|
102
|
+
label: "ESLint",
|
|
103
|
+
9: ["ESLint 9 uses flat config (`eslint.config.js`); `.eslintrc*` is ignored unless `ESLINT_USE_FLAT_CONFIG=false`."],
|
|
104
|
+
},
|
|
105
|
+
vue: {
|
|
106
|
+
label: "Vue",
|
|
107
|
+
3: ["Vue 3: Composition API with `<script setup>`, `defineProps` / `defineEmits`; Options API still works. Vue 2 is end-of-life — do not add Vue 2 patterns like `Vue.extend`."],
|
|
108
|
+
},
|
|
109
|
+
go: {
|
|
110
|
+
label: "Go",
|
|
111
|
+
// keyed by "1.NN" from the go directive
|
|
112
|
+
"1.22": ["Go 1.22+: loop variables are per-iteration; `for i := range 10` works; `net/http` ServeMux supports methods and wildcards (`mux.HandleFunc(\"GET /items/{id}\", …)`)."],
|
|
113
|
+
"1.23": ["Go 1.23+: range-over-func iterators (`iter.Seq`); everything from 1.22 (per-iteration loop vars, method patterns in ServeMux)."],
|
|
114
|
+
"1.24": ["Go 1.24+: generic type aliases; `testing.B.Loop` for benchmarks; `go tool` directives in go.mod; everything from 1.22/1.23."],
|
|
115
|
+
"1.25": ["Go 1.25+: `testing/synctest` for concurrent tests; container-aware GOMAXPROCS; everything from 1.22–1.24."],
|
|
116
|
+
},
|
|
117
|
+
python: {
|
|
118
|
+
label: "Python",
|
|
119
|
+
"3.12": ["Python 3.12+: `type` statement and `class C[T]` generics (PEP 695), `typing.override`, f-strings may nest quotes; `distutils` is gone."],
|
|
120
|
+
"3.13": ["Python 3.13+: `warnings.deprecated`; everything from 3.12 (PEP 695 generics, `typing.override`)."],
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
const major = (range) => {
|
|
125
|
+
const m = /(\d+)/.exec(String(range || ""));
|
|
126
|
+
return m ? m[1] : null;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
/** Read the majors this project runs, from whichever manifests exist. */
|
|
130
|
+
function detectVersions(cwd) {
|
|
131
|
+
const found = [];
|
|
132
|
+
const push = (lib, version, via) => {
|
|
133
|
+
const table = PINS[lib];
|
|
134
|
+
if (!table || !version || !table[version]) return;
|
|
135
|
+
if (found.some((f) => f.lib === lib)) return;
|
|
136
|
+
found.push({ lib, label: table.label, version, via, rules: table[version] });
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
const pkgPath = path.join(cwd, "package.json");
|
|
140
|
+
if (fs.existsSync(pkgPath)) {
|
|
141
|
+
let pkg = null;
|
|
142
|
+
try { pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8")); } catch {}
|
|
143
|
+
const deps = pkg ? { ...pkg.dependencies, ...pkg.devDependencies } : {};
|
|
144
|
+
for (const lib of ["next", "react", "prisma", "tailwindcss", "express", "zod", "eslint", "vue"]) {
|
|
145
|
+
const range = deps[lib] ?? (lib === "prisma" ? deps["@prisma/client"] : undefined);
|
|
146
|
+
if (range) push(lib, major(range), `package.json (${lib} ${range})`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
for (const file of ["pyproject.toml", "requirements.txt"]) {
|
|
151
|
+
const p = path.join(cwd, file);
|
|
152
|
+
if (!fs.existsSync(p)) continue;
|
|
153
|
+
let text = "";
|
|
154
|
+
try { text = fs.readFileSync(p, "utf-8"); } catch { continue; }
|
|
155
|
+
for (const lib of ["pydantic", "sqlalchemy", "django"]) {
|
|
156
|
+
// "pydantic>=2.6", 'pydantic = "^2"', "SQLAlchemy==2.0.30"
|
|
157
|
+
const m = new RegExp(`(?:^|[\\s"'\\[])${lib}\\s*(?:=\\s*)?["']?\\s*[~^>=!<]*=?\\s*(\\d+)`, "im").exec(text);
|
|
158
|
+
if (m) push(lib, m[1], `${file} (${lib} ${m[0].trim().replace(/^["'\[]/, "")})`);
|
|
159
|
+
}
|
|
160
|
+
const py = /requires-python\s*=\s*["']\s*[>=~^]*\s*3\.(\d+)/i.exec(text);
|
|
161
|
+
if (py) push("python", `3.${py[1]}`, `${file} (requires-python)`);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const goMod = path.join(cwd, "go.mod");
|
|
165
|
+
if (fs.existsSync(goMod)) {
|
|
166
|
+
const m = /^go\s+(\d+\.\d+)/m.exec(fs.readFileSync(goMod, "utf-8"));
|
|
167
|
+
if (m) {
|
|
168
|
+
// Pin to the highest table entry at or below the declared version.
|
|
169
|
+
const declared = Number(m[1].split(".")[1]);
|
|
170
|
+
const known = Object.keys(PINS.go).filter((k) => k !== "label").map((k) => Number(k.split(".")[1])).filter((n) => n <= declared).sort((a, b) => b - a)[0];
|
|
171
|
+
if (known !== undefined) push("go", `1.${known}`, `go.mod (go ${m[1]})`);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return found;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** Markdown block written into the agent config by `link`. */
|
|
179
|
+
function renderPins(pins) {
|
|
180
|
+
if (!pins.length) return "";
|
|
181
|
+
const lines = ["### Version pins (detected from this project)", "", "The model's training data may predate these versions. Follow them over habit:", ""];
|
|
182
|
+
for (const p of pins) {
|
|
183
|
+
lines.push(`**${p.label} ${p.version}** — _${p.via}_`);
|
|
184
|
+
for (const r of p.rules) lines.push(`- ${r}`);
|
|
185
|
+
lines.push("");
|
|
186
|
+
}
|
|
187
|
+
return lines.join("\n");
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
module.exports = { PINS, detectVersions, renderPins };
|