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 CHANGED
@@ -1,5 +1,7 @@
1
1
  # arol-ai
2
2
 
3
+ [![tests](https://github.com/benminor/arol/actions/workflows/ci.yml/badge.svg)](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.4",
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": "2027-01-31",
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://www.twilio.com/en-us/changelog",
226
- "summary": "Twilio Notify reaches end of life Jan 31, 2027; after that all Notify API requests will fail. No 1:1 replacement — rebuild with Programmable Messaging / Conversations. Verify the date against Twilio's official EOL notice.",
227
- "source": "https://www.courier.com/blog/twilio-notify-end-of-life"
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",