trimference 0.3.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/BENCHMARK.md +39 -0
- package/CHANGELOG.md +41 -0
- package/CONTRIBUTING.md +43 -0
- package/DEMO.md +106 -0
- package/LICENSE +21 -0
- package/README.md +268 -0
- package/SECURITY.md +17 -0
- package/action.yml +182 -0
- package/dist/baseline.d.ts +13 -0
- package/dist/baseline.d.ts.map +1 -0
- package/dist/baseline.js +23 -0
- package/dist/baseline.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +245 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +31 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +127 -0
- package/dist/config.js.map +1 -0
- package/dist/ecoLLM.d.ts +33 -0
- package/dist/ecoLLM.d.ts.map +1 -0
- package/dist/ecoLLM.js +98 -0
- package/dist/ecoLLM.js.map +1 -0
- package/dist/impact.d.ts +22 -0
- package/dist/impact.d.ts.map +1 -0
- package/dist/impact.js +80 -0
- package/dist/impact.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/models.d.ts +21 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +58 -0
- package/dist/models.js.map +1 -0
- package/dist/prComment.d.ts +36 -0
- package/dist/prComment.d.ts.map +1 -0
- package/dist/prComment.js +45 -0
- package/dist/prComment.js.map +1 -0
- package/dist/reporters/impactTracker.d.ts +21 -0
- package/dist/reporters/impactTracker.d.ts.map +1 -0
- package/dist/reporters/impactTracker.js +54 -0
- package/dist/reporters/impactTracker.js.map +1 -0
- package/dist/reporters/jsonReporter.d.ts +4 -0
- package/dist/reporters/jsonReporter.d.ts.map +1 -0
- package/dist/reporters/jsonReporter.js +34 -0
- package/dist/reporters/jsonReporter.js.map +1 -0
- package/dist/reporters/markdownReporter.d.ts +4 -0
- package/dist/reporters/markdownReporter.d.ts.map +1 -0
- package/dist/reporters/markdownReporter.js +97 -0
- package/dist/reporters/markdownReporter.js.map +1 -0
- package/dist/reporters/sarifReporter.d.ts +4 -0
- package/dist/reporters/sarifReporter.d.ts.map +1 -0
- package/dist/reporters/sarifReporter.js +63 -0
- package/dist/reporters/sarifReporter.js.map +1 -0
- package/dist/reporters/terminalReporter.d.ts +10 -0
- package/dist/reporters/terminalReporter.d.ts.map +1 -0
- package/dist/reporters/terminalReporter.js +80 -0
- package/dist/reporters/terminalReporter.js.map +1 -0
- package/dist/rules/agentLoopWithoutBudget.d.ts +3 -0
- package/dist/rules/agentLoopWithoutBudget.d.ts.map +1 -0
- package/dist/rules/agentLoopWithoutBudget.js +105 -0
- package/dist/rules/agentLoopWithoutBudget.js.map +1 -0
- package/dist/rules/expensiveModelSimpleTask.d.ts +3 -0
- package/dist/rules/expensiveModelSimpleTask.d.ts.map +1 -0
- package/dist/rules/expensiveModelSimpleTask.js +119 -0
- package/dist/rules/expensiveModelSimpleTask.js.map +1 -0
- package/dist/rules/frequentCron.d.ts +3 -0
- package/dist/rules/frequentCron.d.ts.map +1 -0
- package/dist/rules/frequentCron.js +64 -0
- package/dist/rules/frequentCron.js.map +1 -0
- package/dist/rules/helpers.d.ts +65 -0
- package/dist/rules/helpers.d.ts.map +1 -0
- package/dist/rules/helpers.js +383 -0
- package/dist/rules/helpers.js.map +1 -0
- package/dist/rules/hugeContext.d.ts +3 -0
- package/dist/rules/hugeContext.d.ts.map +1 -0
- package/dist/rules/hugeContext.js +74 -0
- package/dist/rules/hugeContext.js.map +1 -0
- package/dist/rules/imageGenerationLoop.d.ts +3 -0
- package/dist/rules/imageGenerationLoop.d.ts.map +1 -0
- package/dist/rules/imageGenerationLoop.js +72 -0
- package/dist/rules/imageGenerationLoop.js.map +1 -0
- package/dist/rules/index.d.ts +14 -0
- package/dist/rules/index.d.ts.map +1 -0
- package/dist/rules/index.js +24 -0
- package/dist/rules/index.js.map +1 -0
- package/dist/rules/missingRateLimit.d.ts +3 -0
- package/dist/rules/missingRateLimit.d.ts.map +1 -0
- package/dist/rules/missingRateLimit.js +78 -0
- package/dist/rules/missingRateLimit.js.map +1 -0
- package/dist/rules/noLlmCache.d.ts +3 -0
- package/dist/rules/noLlmCache.d.ts.map +1 -0
- package/dist/rules/noLlmCache.js +71 -0
- package/dist/rules/noLlmCache.js.map +1 -0
- package/dist/rules/noTokenLimit.d.ts +3 -0
- package/dist/rules/noTokenLimit.d.ts.map +1 -0
- package/dist/rules/noTokenLimit.js +59 -0
- package/dist/rules/noTokenLimit.js.map +1 -0
- package/dist/rules/repeatedEmbeddings.d.ts +3 -0
- package/dist/rules/repeatedEmbeddings.d.ts.map +1 -0
- package/dist/rules/repeatedEmbeddings.js +81 -0
- package/dist/rules/repeatedEmbeddings.js.map +1 -0
- package/dist/rules/sequentialLlmCalls.d.ts +3 -0
- package/dist/rules/sequentialLlmCalls.d.ts.map +1 -0
- package/dist/rules/sequentialLlmCalls.js +69 -0
- package/dist/rules/sequentialLlmCalls.js.map +1 -0
- package/dist/scanner.d.ts +23 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +217 -0
- package/dist/scanner.js.map +1 -0
- package/dist/types.d.ts +93 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -0
- package/package.json +75 -0
package/BENCHMARK.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Accuracy benchmark
|
|
2
|
+
|
|
3
|
+
Trimference is a heuristic review tool. This benchmark is intentionally modest and
|
|
4
|
+
reproducible; it does not claim real-world precision from curated examples.
|
|
5
|
+
|
|
6
|
+
## Launch acceptance checks
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
npm run verify
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
The command requires:
|
|
13
|
+
|
|
14
|
+
1. TypeScript compilation succeeds.
|
|
15
|
+
2. All positive and negative rule fixtures pass.
|
|
16
|
+
3. The scanner's own `src/` directory produces zero findings.
|
|
17
|
+
4. The cleaner example produces zero findings.
|
|
18
|
+
|
|
19
|
+
The intentionally wasteful example must continue to exercise every safeguard
|
|
20
|
+
category. Its exact finding count is not treated as an accuracy metric.
|
|
21
|
+
|
|
22
|
+
## What the fixtures cover
|
|
23
|
+
|
|
24
|
+
- Executable calls versus comments, strings, and regex definitions
|
|
25
|
+
- Cached and uncached calls
|
|
26
|
+
- Bounded and unbounded context/output
|
|
27
|
+
- Persisted and repeated embeddings
|
|
28
|
+
- Image generation inside and outside loops
|
|
29
|
+
- AI and non-AI scheduled work
|
|
30
|
+
- Budgeted and unbudgeted agent loops
|
|
31
|
+
- Rate-limited and unprotected public routes
|
|
32
|
+
- Common JavaScript/TypeScript and selected Python call shapes
|
|
33
|
+
|
|
34
|
+
## Next benchmark milestone
|
|
35
|
+
|
|
36
|
+
Before describing Trimference as low-noise or publishing a precision percentage,
|
|
37
|
+
build an anonymized corpus of representative repositories and label every call
|
|
38
|
+
site manually. Report per-rule precision and recall, corpus selection, scanner
|
|
39
|
+
version, and all exclusions.
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes are documented here.
|
|
4
|
+
|
|
5
|
+
## 0.3.0 - Unreleased
|
|
6
|
+
|
|
7
|
+
### Renamed
|
|
8
|
+
|
|
9
|
+
- The project, npm package, CLI, Action, config, suppression directives, and
|
|
10
|
+
reports are now **Trimference**. The former config filename, inline directive
|
|
11
|
+
prefix, public type names, and PR marker remain available as migration aliases.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- Evidence-first terminal and Markdown efficiency reviews
|
|
16
|
+
- Finding confidence and severity counts in summaries
|
|
17
|
+
- Baseline creation and suppression
|
|
18
|
+
- `--fail-on` CI thresholds with exit code 2
|
|
19
|
+
- Changed-file scanning with `--changed-since`
|
|
20
|
+
- SARIF 2.1.0 output for code-scanning integrations
|
|
21
|
+
- Glob-aware ignored paths
|
|
22
|
+
- Observable rule execution errors
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- Human reports no longer present carbon/water levels or a repository waste score
|
|
27
|
+
- JSON schema v2 reports operational risk instead of carbon/water estimates
|
|
28
|
+
- Repository priority scoring is monotonic for API compatibility
|
|
29
|
+
- Call-site rules ignore comments, quoted examples, and regex definitions
|
|
30
|
+
- Context and scheduled-work findings now require nearby/proven AI work
|
|
31
|
+
- GitHub Action uses a matching pinned npm version
|
|
32
|
+
- README positioning now leads with cost, latency, reliability, and review
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
|
|
36
|
+
- Fixing low-severity findings can no longer increase the compatibility score
|
|
37
|
+
- Trimference's own rule definitions no longer appear as executable model calls
|
|
38
|
+
|
|
39
|
+
## 0.2.1 - 2026-07-01
|
|
40
|
+
|
|
41
|
+
- Added GitHub PR comment mode and expanded launch documentation.
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thanks for helping make Trimference more accurate and useful.
|
|
4
|
+
|
|
5
|
+
## The most useful contributions
|
|
6
|
+
|
|
7
|
+
- Minimal false-positive or false-negative fixtures
|
|
8
|
+
- Provider/framework call patterns from real applications
|
|
9
|
+
- Report usability improvements
|
|
10
|
+
- Documentation corrections
|
|
11
|
+
|
|
12
|
+
Accuracy matters more than rule count. A new rule should have a narrow claim,
|
|
13
|
+
clear confidence, positive and negative fixtures, and a practical remediation.
|
|
14
|
+
|
|
15
|
+
## Development
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm ci
|
|
19
|
+
npm run build
|
|
20
|
+
npm test
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Run the examples as a smoke test:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
node dist/cli.js scan --path examples/wasteful-ai-app --summary
|
|
27
|
+
node dist/cli.js scan --path examples/cleaner-ai-app
|
|
28
|
+
node dist/cli.js scan --path src --summary
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The implementation source should not flag its own pattern definitions as
|
|
32
|
+
executable AI calls.
|
|
33
|
+
|
|
34
|
+
## Pull requests
|
|
35
|
+
|
|
36
|
+
Please include:
|
|
37
|
+
|
|
38
|
+
1. A short explanation of the behavior change.
|
|
39
|
+
2. Tests covering a true positive and a nearby negative case.
|
|
40
|
+
3. Updated documentation when output or configuration changes.
|
|
41
|
+
|
|
42
|
+
Do not add precise cost or environmental claims without a reproducible,
|
|
43
|
+
reviewable methodology and clearly stated inputs.
|
package/DEMO.md
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Trimference demo
|
|
2
|
+
|
|
3
|
+
Trimference is a local static review for LLM application efficiency safeguards.
|
|
4
|
+
It reports probable cost, latency, and reliability risks with source evidence
|
|
5
|
+
and explicit confidence. It does not measure runtime usage or environmental
|
|
6
|
+
impact.
|
|
7
|
+
|
|
8
|
+
## 20-second demo
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
mkdir trimference-demo && cd trimference-demo
|
|
12
|
+
cat > bad.ts <<'EOF'
|
|
13
|
+
import OpenAI from "openai";
|
|
14
|
+
|
|
15
|
+
const openai = new OpenAI();
|
|
16
|
+
|
|
17
|
+
export async function classify(text: string) {
|
|
18
|
+
return openai.chat.completions.create({
|
|
19
|
+
model: "gpt-4o",
|
|
20
|
+
messages: [{ role: "user", content: `classify this: ${text}` }]
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
EOF
|
|
24
|
+
|
|
25
|
+
npx trimference scan --path .
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The review should identify a likely repeatable uncached call, a model
|
|
29
|
+
right-sizing opportunity, and a missing output limit.
|
|
30
|
+
|
|
31
|
+
## Repository examples
|
|
32
|
+
|
|
33
|
+
From a source checkout:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm ci
|
|
37
|
+
npm run build
|
|
38
|
+
|
|
39
|
+
node dist/cli.js scan --path examples/wasteful-ai-app --summary
|
|
40
|
+
node dist/cli.js scan --path examples/cleaner-ai-app
|
|
41
|
+
node dist/cli.js scan --path src --summary
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The wasteful example exercises all review areas. The cleaner example should be
|
|
45
|
+
clean. The scanner source should also be clean: comments, quoted examples, and
|
|
46
|
+
regex rule definitions are not executable call sites.
|
|
47
|
+
|
|
48
|
+
## Markdown review
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
node dist/cli.js scan \
|
|
52
|
+
--path examples/wasteful-ai-app \
|
|
53
|
+
--markdown \
|
|
54
|
+
--output trimference-report.md
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The report front-loads severity counts, safeguard areas, and top actions. Each
|
|
58
|
+
finding has a clickable location and evidence row; verbose fix recipes are
|
|
59
|
+
collapsed.
|
|
60
|
+
|
|
61
|
+
## Adopt with a baseline
|
|
62
|
+
|
|
63
|
+
Record current debt once:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
node dist/cli.js scan \
|
|
67
|
+
--path . \
|
|
68
|
+
--write-baseline trimference-baseline.json
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Then report or gate only on new findings:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
node dist/cli.js scan \
|
|
75
|
+
--path . \
|
|
76
|
+
--baseline trimference-baseline.json \
|
|
77
|
+
--fail-on high
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## GitHub pull requests
|
|
81
|
+
|
|
82
|
+
```yaml
|
|
83
|
+
name: Trimference
|
|
84
|
+
|
|
85
|
+
on:
|
|
86
|
+
pull_request:
|
|
87
|
+
|
|
88
|
+
permissions:
|
|
89
|
+
contents: read
|
|
90
|
+
pull-requests: write
|
|
91
|
+
|
|
92
|
+
jobs:
|
|
93
|
+
trimference:
|
|
94
|
+
runs-on: ubuntu-latest
|
|
95
|
+
steps:
|
|
96
|
+
- uses: actions/checkout@v4
|
|
97
|
+
- uses: psamme/trimference@v0.3.0
|
|
98
|
+
with:
|
|
99
|
+
path: "."
|
|
100
|
+
baseline: "trimference-baseline.json"
|
|
101
|
+
fail-on: "high"
|
|
102
|
+
comment: "true"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
The Action writes the report before enforcing the threshold, and it updates one
|
|
106
|
+
stable PR comment instead of posting duplicates.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Trimference contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
# Trimference
|
|
2
|
+
|
|
3
|
+
**A local efficiency review for LLM application code.**
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/trimference)
|
|
6
|
+
[](https://github.com/psamme/trimference/actions/workflows/trimference.yml)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
|
|
9
|
+
Trimference scans source code for patterns that can amplify LLM cost, latency,
|
|
10
|
+
and reliability risk: uncached repeatable calls, unbounded context and output,
|
|
11
|
+
repeated embeddings, model right-sizing opportunities, unbudgeted agent loops,
|
|
12
|
+
and public AI routes without rate limits.
|
|
13
|
+
|
|
14
|
+
It is an early static heuristic scanner—not production telemetry or carbon
|
|
15
|
+
accounting. Findings are review prompts with explicit confidence, source
|
|
16
|
+
evidence, and fix recipes.
|
|
17
|
+
|
|
18
|
+
> **Renamed in 0.3.0:** Trimference was previously published as `ecolint-ai`.
|
|
19
|
+
> The former config filename, suppression prefix, and public type names remain
|
|
20
|
+
> available as migration aliases.
|
|
21
|
+
|
|
22
|
+
## Try it
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npx trimference scan --path .
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
No provider key is required. The scanner does not upload source code or call an
|
|
29
|
+
AI provider. `npx` may download the package from npm on first use.
|
|
30
|
+
|
|
31
|
+
Useful variants:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npx trimference scan --path . --summary
|
|
35
|
+
npx trimference scan --path . --markdown --output trimference-report.md
|
|
36
|
+
npx trimference scan --path . --json
|
|
37
|
+
npx trimference scan --path . --sarif --output trimference.sarif
|
|
38
|
+
npx trimference scan --path . --fail-on high
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## What the review looks like
|
|
42
|
+
|
|
43
|
+
```text
|
|
44
|
+
Trimference efficiency review
|
|
45
|
+
|
|
46
|
+
Scanned 6 files in 41ms.
|
|
47
|
+
Found 17 review item(s): 4 high · 9 medium · 4 low
|
|
48
|
+
|
|
49
|
+
Safeguards to review:
|
|
50
|
+
- Repeated inference: 8
|
|
51
|
+
- Unbounded generation: 4
|
|
52
|
+
- Frequent background work: 1
|
|
53
|
+
|
|
54
|
+
Top opportunities:
|
|
55
|
+
1. Cap repeated image generation in lib/image.ts
|
|
56
|
+
2. Add step, time, and token/cost budgets to agent loops.
|
|
57
|
+
|
|
58
|
+
[HIGH · MEDIUM CONFIDENCE] Agent loop without obvious budget
|
|
59
|
+
lib/agent.ts:8 · agent-loop-without-budget · Repeated inference
|
|
60
|
+
while (true) {
|
|
61
|
+
Issue: This agentic flow appears to run without an obvious budget.
|
|
62
|
+
Fix: Add explicit max steps, timeouts, token caps, and/or cost budgets.
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Terminal output is compact by default. Markdown reports include a summary table,
|
|
66
|
+
clickable locations, evidence, and collapsed fix details. JSON is available for
|
|
67
|
+
automation, and SARIF 2.1.0 is available for code-scanning integrations. Reports
|
|
68
|
+
describe operational compute and cost risk; they do not manufacture carbon or
|
|
69
|
+
water estimates from source code.
|
|
70
|
+
|
|
71
|
+
## Why static analysis?
|
|
72
|
+
|
|
73
|
+
Provider dashboards and runtime observability explain what already ran. Trimference
|
|
74
|
+
works earlier: during local development and review, before a risky call pattern
|
|
75
|
+
is merged. Use it alongside runtime cost and quality telemetry, not instead of
|
|
76
|
+
them.
|
|
77
|
+
|
|
78
|
+
## Rules
|
|
79
|
+
|
|
80
|
+
| Rule | Review area | Default severity | What it looks for |
|
|
81
|
+
|---|---|---|---|
|
|
82
|
+
| `no-llm-cache` | Repeated inference | medium; high for likely repeatable tasks | Model calls without nearby cache/dedupe logic |
|
|
83
|
+
| `huge-context` | Token bloat | medium | Unbounded history/document variables close to a proven model call |
|
|
84
|
+
| `expensive-model-simple-task` | Model right-sizing | medium | Larger model names near classification/extraction/routing work |
|
|
85
|
+
| `repeated-embeddings` | Redundant embedding | high | Embedding calls without persistence, especially in loops |
|
|
86
|
+
| `image-generation-loop` | Repeated image generation | high | Image generation close to loops or retries |
|
|
87
|
+
| `frequent-cron` | Frequent background work | medium | Frequent schedules in files that perform AI work |
|
|
88
|
+
| `no-token-limit` | Unbounded generation | low | Model calls without a nearby output cap |
|
|
89
|
+
| `sequential-llm-calls` | Repeated inference | medium | Multiple nearby model calls that may be one flow |
|
|
90
|
+
| `agent-loop-without-budget` | Repeated inference | high | Agent/tool loops without nearby step, time, token, or cost limits |
|
|
91
|
+
| `missing-rate-limit` | Repeated inference | medium | Public AI routes without an obvious quota or rate limit |
|
|
92
|
+
|
|
93
|
+
Rules first prove that relevant calls occur in executable code; comments,
|
|
94
|
+
quoted examples, regex literals, and documentation are not treated as call
|
|
95
|
+
sites. The scanner still uses lexical heuristics rather than full data-flow
|
|
96
|
+
analysis, so review findings before acting on them.
|
|
97
|
+
|
|
98
|
+
## CI and pull requests
|
|
99
|
+
|
|
100
|
+
The GitHub Action writes the Markdown review to the job summary and can update a
|
|
101
|
+
single PR comment:
|
|
102
|
+
|
|
103
|
+
```yaml
|
|
104
|
+
name: Trimference
|
|
105
|
+
|
|
106
|
+
on:
|
|
107
|
+
pull_request:
|
|
108
|
+
|
|
109
|
+
permissions:
|
|
110
|
+
contents: read
|
|
111
|
+
pull-requests: write
|
|
112
|
+
|
|
113
|
+
jobs:
|
|
114
|
+
trimference:
|
|
115
|
+
runs-on: ubuntu-latest
|
|
116
|
+
steps:
|
|
117
|
+
- uses: actions/checkout@v4
|
|
118
|
+
- uses: psamme/trimference@v0.3.0
|
|
119
|
+
with:
|
|
120
|
+
path: "."
|
|
121
|
+
comment: "true"
|
|
122
|
+
fail-on: "high"
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
The action tag runs the matching pinned npm version. Reporting happens before
|
|
126
|
+
the optional threshold gate, so a failed check still leaves an actionable
|
|
127
|
+
summary.
|
|
128
|
+
|
|
129
|
+
### Adopt without failing on existing debt
|
|
130
|
+
|
|
131
|
+
Create a baseline once:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
npx trimference scan --path . --write-baseline trimference-baseline.json
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Then report or fail only on findings not in that baseline:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
npx trimference scan --path . \
|
|
141
|
+
--baseline trimference-baseline.json \
|
|
142
|
+
--fail-on high
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
In the Action:
|
|
146
|
+
|
|
147
|
+
```yaml
|
|
148
|
+
with:
|
|
149
|
+
path: "."
|
|
150
|
+
baseline: "trimference-baseline.json"
|
|
151
|
+
fail-on: "high"
|
|
152
|
+
comment: "true"
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Baseline fingerprints use rule, relative path, and normalized source evidence,
|
|
156
|
+
so unrelated line-number changes do not normally resurrect accepted findings.
|
|
157
|
+
|
|
158
|
+
For a local diff-only review, make sure the base ref exists in the checkout:
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
npx trimference scan --path . --changed-since origin/main --fail-on high
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## CLI
|
|
165
|
+
|
|
166
|
+
```text
|
|
167
|
+
trimference scan [options]
|
|
168
|
+
|
|
169
|
+
--path <path> Path to scan (default: .)
|
|
170
|
+
--summary Summary only
|
|
171
|
+
--max-findings <n> Terminal detail limit; 0 shows all
|
|
172
|
+
--markdown Markdown to stdout
|
|
173
|
+
--json JSON to stdout
|
|
174
|
+
--sarif SARIF 2.1.0 to stdout
|
|
175
|
+
--output <file> Write Markdown, JSON with --json, or SARIF with --sarif
|
|
176
|
+
--min-severity <level> low | medium | high
|
|
177
|
+
--provider <name> openai | anthropic | google | mistral
|
|
178
|
+
--baseline <file> Hide accepted baseline findings
|
|
179
|
+
--write-baseline <file> Record current findings and exit
|
|
180
|
+
--changed-since <git-ref> Scan only files changed since a local Git ref
|
|
181
|
+
--fail-on <level> none | low | medium | high; exits 2 on a match
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Exit codes:
|
|
185
|
+
|
|
186
|
+
- `0`: scan completed and the configured gate passed
|
|
187
|
+
- `1`: invalid input, configuration, or scan failure
|
|
188
|
+
- `2`: findings met the `--fail-on` threshold
|
|
189
|
+
|
|
190
|
+
## Configuration and suppressions
|
|
191
|
+
|
|
192
|
+
Run `trimference init` to create `trimference.config.json`:
|
|
193
|
+
|
|
194
|
+
```json
|
|
195
|
+
{
|
|
196
|
+
"minSeverity": "low",
|
|
197
|
+
"ignoredRules": [],
|
|
198
|
+
"ignoredPaths": ["examples/**", "**/*.fixture.ts"],
|
|
199
|
+
"provider": "openai",
|
|
200
|
+
"baseline": "trimference-baseline.json",
|
|
201
|
+
"failOn": "none"
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
CLI flags override config. `ignoredPaths` accepts glob patterns; entries without
|
|
206
|
+
`*` or `?` continue to work as path substrings.
|
|
207
|
+
|
|
208
|
+
Inline suppressions are also supported:
|
|
209
|
+
|
|
210
|
+
```ts
|
|
211
|
+
// trimference-disable-next-line no-llm-cache -- personalized response, no safe reuse
|
|
212
|
+
await openai.responses.create({ model, input });
|
|
213
|
+
|
|
214
|
+
// trimference-disable no-token-limit
|
|
215
|
+
await runProviderManagedGeneration();
|
|
216
|
+
// trimference-enable no-token-limit
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Supported directives are `trimference-disable-next-line`, `trimference-disable-line`,
|
|
220
|
+
and `trimference-disable` / `trimference-enable` blocks.
|
|
221
|
+
|
|
222
|
+
## Library API
|
|
223
|
+
|
|
224
|
+
```ts
|
|
225
|
+
import {
|
|
226
|
+
scan,
|
|
227
|
+
renderMarkdownReport,
|
|
228
|
+
findingFingerprint,
|
|
229
|
+
} from "trimference";
|
|
230
|
+
|
|
231
|
+
const result = await scan({ path: ".", minSeverity: "medium" });
|
|
232
|
+
console.log(renderMarkdownReport(result));
|
|
233
|
+
console.log(result.findings.map(findingFingerprint));
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
The `trimInference` helper provides the existing local model-tier advisor;
|
|
237
|
+
`ecoLLM` remains as a deprecated compatibility alias. Its model names are
|
|
238
|
+
illustrative and manually maintained. Validate model choices with your own
|
|
239
|
+
quality evaluations and current provider pricing.
|
|
240
|
+
|
|
241
|
+
## Limitations
|
|
242
|
+
|
|
243
|
+
- Lexical/static heuristics cannot prove runtime behavior or request volume.
|
|
244
|
+
- Nearby calls may be independent; nearby safeguards may apply to a different call.
|
|
245
|
+
- Framework and provider coverage is strongest for common JavaScript/TypeScript SDKs.
|
|
246
|
+
- Python files are discoverable, but Python-specific framework coverage is still early.
|
|
247
|
+
- Model right-sizing must be validated against application-specific quality tests.
|
|
248
|
+
- Trimference does not measure exact spend, emissions, water, or infrastructure energy.
|
|
249
|
+
|
|
250
|
+
False-positive reports and small representative fixtures are especially useful.
|
|
251
|
+
See [BENCHMARK.md](BENCHMARK.md) and [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
252
|
+
|
|
253
|
+
## Development
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
npm ci
|
|
257
|
+
npm run build
|
|
258
|
+
npm test
|
|
259
|
+
npm run scan:example
|
|
260
|
+
npm run verify
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
The repository includes an intentionally wasteful example and a cleaner
|
|
264
|
+
counterpart under `examples/`.
|
|
265
|
+
|
|
266
|
+
## License
|
|
267
|
+
|
|
268
|
+
[MIT](LICENSE)
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Security policy
|
|
2
|
+
|
|
3
|
+
## Reporting a vulnerability
|
|
4
|
+
|
|
5
|
+
Please do not open a public issue for a vulnerability that could put users or
|
|
6
|
+
their source code at risk. Use GitHub's private vulnerability reporting for
|
|
7
|
+
this repository when available, or contact the maintainer through the address
|
|
8
|
+
listed on the npm package.
|
|
9
|
+
|
|
10
|
+
Include reproduction steps, affected versions, and the likely impact. You can
|
|
11
|
+
expect an acknowledgement within seven days.
|
|
12
|
+
|
|
13
|
+
## Data handling
|
|
14
|
+
|
|
15
|
+
Trimference reads source files from the requested local path. The scanner does not
|
|
16
|
+
upload source or call an AI provider. Package installation through npm and use
|
|
17
|
+
of GitHub Actions still involve those services under their respective policies.
|