@aidriftline/driftline 0.1.11 → 0.1.12
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 +3 -0
- package/package.json +1 -1
- package/src/cli.js +4 -4
- package/src/mcp.js +12 -2
- package/src/run.js +1 -1
package/README.md
CHANGED
|
@@ -76,6 +76,9 @@ If you are an agent (Claude Code, Cursor, Copilot, Codex…) changing code that
|
|
|
76
76
|
|
|
77
77
|
Driftline also runs as an [MCP](https://modelcontextprotocol.io) server, so your agent can ask it directly. Tools: `check_models` (status, date and replacement for a list of IDs), `scan_project` (retired and retiring IDs in a folder, with file and line) and `upcoming_retirements` (what retires in the next N days). It reads the daily-updated list from aidriftline.com and falls back to the copy in the package when offline.
|
|
78
78
|
|
|
79
|
+
[](https://cursor.com/en/install-mcp?name=driftline&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBhaWRyaWZ0bGluZS9kcmlmdGxpbmUiLCJtY3AiXX0%3D)
|
|
80
|
+
[](https://insiders.vscode.dev/redirect?url=vscode%3Amcp%2Finstall%3F%257B%2522name%2522%253A%2522driftline%2522%252C%2522command%2522%253A%2522npx%2522%252C%2522args%2522%253A%255B%2522-y%2522%252C%2522%2540aidriftline%252Fdriftline%2522%252C%2522mcp%2522%255D%257D)
|
|
81
|
+
|
|
79
82
|
Claude Code:
|
|
80
83
|
|
|
81
84
|
```sh
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aidriftline/driftline",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
4
4
|
"description": "Finds OpenAI, Anthropic and Google model IDs in your code and warns before they are retired. CLI, GitHub Action and MCP server.",
|
|
5
5
|
"mcpName": "io.github.AI-Driftline/driftline",
|
|
6
6
|
"type": "module",
|
package/src/cli.js
CHANGED
|
@@ -28,10 +28,10 @@ function accountFromGit() {
|
|
|
28
28
|
const HELP = `Driftline: finds AI model IDs in your code and warns before they are retired.
|
|
29
29
|
|
|
30
30
|
Usage:
|
|
31
|
-
npx
|
|
32
|
-
npx
|
|
33
|
-
npx
|
|
34
|
-
npx
|
|
31
|
+
npx @aidriftline/driftline [directory] scan and print the report
|
|
32
|
+
npx @aidriftline/driftline activate <license-key> register this GitHub account for Pro
|
|
33
|
+
npx @aidriftline/driftline deactivate <code> free that account's slot
|
|
34
|
+
npx @aidriftline/driftline mcp MCP server for coding agents (stdio)
|
|
35
35
|
|
|
36
36
|
Options:
|
|
37
37
|
--json print the scan as JSON (for scripts and coding agents)
|
package/src/mcp.js
CHANGED
|
@@ -79,12 +79,22 @@ const TOOLS = [
|
|
|
79
79
|
},
|
|
80
80
|
];
|
|
81
81
|
|
|
82
|
+
// When a model has to move, the open question is whether the replacement answers the same way.
|
|
83
|
+
const SWITCHING = new Set(["retired", "at-risk", "deprecated"]);
|
|
84
|
+
function nextStep(rows) {
|
|
85
|
+
const r = rows.find((x) => x.replacement && (SWITCHING.has(x.status) || x.routes));
|
|
86
|
+
if (!r) return {};
|
|
87
|
+
return { next_step: `Before moving ${r.id} to ${r.replacement}, test the prompts this app really sends on both models: answers often change between model versions. ` +
|
|
88
|
+
"Driftline Pro runs each prompt on the current model and the replacement in GitHub Actions and shows what changed (https://aidriftline.com/#drift)." };
|
|
89
|
+
}
|
|
90
|
+
|
|
82
91
|
export async function callTool(name, args = {}, { reg, source, today = new Date() }) {
|
|
83
92
|
const meta = { registry_checked: reg.checked, registry_source: source, all_dates: "https://aidriftline.com/models/" };
|
|
84
93
|
if (name === "check_models") {
|
|
85
94
|
const ids = Array.isArray(args.ids) ? args.ids.filter((x) => typeof x === "string").slice(0, 100) : [];
|
|
86
95
|
if (!ids.length) throw new Error("ids must be a non-empty array of model ID strings");
|
|
87
|
-
|
|
96
|
+
const models = ids.map((id) => describe(id, reg, today));
|
|
97
|
+
return { models, ...nextStep(models), ...meta };
|
|
88
98
|
}
|
|
89
99
|
if (name === "scan_project") {
|
|
90
100
|
const root = resolve(args.path || ".");
|
|
@@ -94,7 +104,7 @@ export async function callTool(name, args = {}, { reg, source, today = new Date(
|
|
|
94
104
|
const order = { retired: 0, "at-risk": 1, deprecated: 2, active: 3, unknown: 4 };
|
|
95
105
|
rows.sort((a, b) => order[a.status] - order[b.status] || (a.days_left ?? 1e9) - (b.days_left ?? 1e9));
|
|
96
106
|
return { scanned: root, model_references: hits.length, flagged: rows.length, findings: rows.slice(0, 200),
|
|
97
|
-
...(rows.length > 200 ? { truncated: true } : {}), ...meta };
|
|
107
|
+
...(rows.length > 200 ? { truncated: true } : {}), ...nextStep(rows), ...meta };
|
|
98
108
|
}
|
|
99
109
|
if (name === "upcoming_retirements") {
|
|
100
110
|
const days = Number.isFinite(args.days) && args.days > 0 ? Math.min(args.days, 3650) : 90;
|
package/src/run.js
CHANGED
|
@@ -57,7 +57,7 @@ export async function run({
|
|
|
57
57
|
notices.push(`Drift tests stopped: ${e.message}. The scan results above are complete.`);
|
|
58
58
|
}
|
|
59
59
|
} else if (findings.some((f) => FLAGGED.has(f.status))) {
|
|
60
|
-
notices.push(`
|
|
60
|
+
notices.push(`Before you switch, test the prompts your app really sends on the replacement model: list them in ${promptsFile} and Driftline Pro runs each one on both models and shows what changed. https://aidriftline.com/#drift`);
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
const atRisk = findings.filter((f) => !f.doc && (f.status === "retired" || f.status === "at-risk")).length;
|