arol-ai 0.1.4 → 0.1.6
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 +22 -0
- package/dist/cli.js +1 -8
- package/dist/scanner.js +1 -0
- package/dist/status.js +14 -0
- package/package.json +5 -2
- package/src/data/deprecations.json +4 -5
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# arol-ai
|
|
2
2
|
|
|
3
|
+
[](https://github.com/benminor/arol/actions/workflows/ci.yml)
|
|
4
|
+
|
|
3
5
|
Scan a local code repo for usage of third-party APIs/SDKs that have **upcoming deprecations**, and print a clean report.
|
|
4
6
|
|
|
5
7
|
**Everything runs locally.** No network calls, no telemetry, no uploads, no auth. Your code never leaves your machine.
|
|
@@ -134,6 +136,26 @@ npx arol-ai scan --within 7 # only fail when a sunset is within a week
|
|
|
134
136
|
|
|
135
137
|
Colors are automatically disabled when output is not a TTY (e.g. piped to a file), or when `NO_COLOR` is set. Use `FORCE_COLOR=1` to force them on.
|
|
136
138
|
|
|
139
|
+
## Run arol in CI
|
|
140
|
+
|
|
141
|
+
Add a workflow file at `.github/workflows/arol.yml` in **your own repo**. GitHub Actions runs anything in `.github/workflows/` automatically — the filename is arbitrary — and this one triggers on every `push` and `pull_request`:
|
|
142
|
+
|
|
143
|
+
```yaml
|
|
144
|
+
name: arol deprecation scan
|
|
145
|
+
on: [push, pull_request]
|
|
146
|
+
jobs:
|
|
147
|
+
scan:
|
|
148
|
+
runs-on: ubuntu-latest
|
|
149
|
+
steps:
|
|
150
|
+
- uses: actions/checkout@v4
|
|
151
|
+
- uses: actions/setup-node@v4
|
|
152
|
+
with: { node-version: 20 }
|
|
153
|
+
- run: npx arol-ai scan
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
1. **Exit codes fail the build only on real breaks.** The scan exits non-zero only for high-severity or imminent dated deprecations, and stays warn-only (exit `0`) for `deprecated`/`medium` findings — so it won't block a PR over a deprecation that has no deadline.
|
|
157
|
+
2. **Portable to any CI.** `npx arol-ai scan` is the one line that matters (GitLab CI, CircleCI, a cron job, etc.); only the YAML wrapper above is GitHub-specific.
|
|
158
|
+
|
|
137
159
|
## The dataset (`deprecations.json`)
|
|
138
160
|
|
|
139
161
|
All detections are **data-driven** — the bundled dataset lives at
|
package/dist/cli.js
CHANGED
|
@@ -139,14 +139,7 @@ function runScan(targetPath, opts) {
|
|
|
139
139
|
const within = Number.isFinite(parsedWithin) && parsedWithin >= 0
|
|
140
140
|
? parsedWithin
|
|
141
141
|
: DEFAULT_WITHIN_DAYS;
|
|
142
|
-
const tripped = result.findings.some((f) =>
|
|
143
|
-
if (f.deprecation.severity === "high")
|
|
144
|
-
return true;
|
|
145
|
-
if ((0, status_1.effectiveStatus)(f.deprecation, now) !== "scheduled")
|
|
146
|
-
return false;
|
|
147
|
-
const days = (0, status_1.daysUntil)(f.deprecation.sunset_date, now);
|
|
148
|
-
return days !== null && days >= 0 && days <= within;
|
|
149
|
-
});
|
|
142
|
+
const tripped = result.findings.some((f) => (0, status_1.isActionable)(f.deprecation, now, within));
|
|
150
143
|
if (tripped)
|
|
151
144
|
process.exitCode = 1;
|
|
152
145
|
}
|
package/dist/scanner.js
CHANGED
|
@@ -36,6 +36,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
36
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.modelRegexSource = modelRegexSource;
|
|
39
40
|
exports.scanRepo = scanRepo;
|
|
40
41
|
const fs = __importStar(require("fs"));
|
|
41
42
|
const path = __importStar(require("path"));
|
package/dist/status.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.parseSunsetDate = parseSunsetDate;
|
|
4
4
|
exports.daysUntil = daysUntil;
|
|
5
5
|
exports.effectiveStatus = effectiveStatus;
|
|
6
|
+
exports.isActionable = isActionable;
|
|
6
7
|
const MS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
7
8
|
/** Midnight-UTC timestamp for a Date's calendar day. */
|
|
8
9
|
function startOfDayUTC(d) {
|
|
@@ -43,3 +44,16 @@ function effectiveStatus(d, now) {
|
|
|
43
44
|
return "deprecated";
|
|
44
45
|
return t < startOfDayUTC(now) ? "retired" : "scheduled";
|
|
45
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Whether a finding should fail the CI gate (non-zero exit): any high-severity
|
|
49
|
+
* finding, or a scheduled finding landing within `within` days. Dateless
|
|
50
|
+
* "deprecated" and non-imminent medium/low findings are warn-only.
|
|
51
|
+
*/
|
|
52
|
+
function isActionable(d, now, within) {
|
|
53
|
+
if (d.severity === "high")
|
|
54
|
+
return true;
|
|
55
|
+
if (effectiveStatus(d, now) !== "scheduled")
|
|
56
|
+
return false;
|
|
57
|
+
const days = daysUntil(d.sunset_date, now);
|
|
58
|
+
return days !== null && days >= 0 && days <= within;
|
|
59
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "arol-ai",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Scan a local repo for upcoming third-party API/SDK deprecations. Fully local — no network, no telemetry, your code never leaves the machine.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"deprecation",
|
|
@@ -29,6 +29,8 @@
|
|
|
29
29
|
"scripts": {
|
|
30
30
|
"build": "tsc",
|
|
31
31
|
"scan": "node dist/cli.js scan",
|
|
32
|
+
"test": "vitest run",
|
|
33
|
+
"test:watch": "vitest",
|
|
32
34
|
"prepublishOnly": "npm run build"
|
|
33
35
|
},
|
|
34
36
|
"dependencies": {
|
|
@@ -37,6 +39,7 @@
|
|
|
37
39
|
},
|
|
38
40
|
"devDependencies": {
|
|
39
41
|
"@types/node": "^22.10.0",
|
|
40
|
-
"typescript": "^5.7.2"
|
|
42
|
+
"typescript": "^5.7.2",
|
|
43
|
+
"vitest": "^4.1.8"
|
|
41
44
|
}
|
|
42
45
|
}
|
|
@@ -216,15 +216,14 @@
|
|
|
216
216
|
"severity": "high",
|
|
217
217
|
"match": "pattern",
|
|
218
218
|
"applies_to": ["py", "js", "ts", "jsx", "tsx", "mjs"],
|
|
219
|
-
"sunset_date": "
|
|
220
|
-
"date_confidence": "verify",
|
|
219
|
+
"sunset_date": "2025-12-31",
|
|
221
220
|
"detect": {
|
|
222
221
|
"sdk": ["twilio"],
|
|
223
222
|
"patterns": ["notify\\.v1", "\\.notify\\.services", "client\\.notify"]
|
|
224
223
|
},
|
|
225
|
-
"migration_url": "https://
|
|
226
|
-
"summary": "Twilio Notify
|
|
227
|
-
"source": "https://www.
|
|
224
|
+
"migration_url": "https://support.twilio.com/hc/en-us/articles/9198083260571-Transitioning-off-Notify",
|
|
225
|
+
"summary": "Twilio Notify reached end of life December 31, 2025; Notify API requests now fail. No 1:1 replacement — rebuild with Programmable Messaging / Conversations.",
|
|
226
|
+
"source": "https://www.twilio.com/en-us/changelog/notify-api-end-of-life-further-extension-notice"
|
|
228
227
|
},
|
|
229
228
|
{
|
|
230
229
|
"id": "twilio-programmable-chat-retired",
|