@ossiq/cli-darwin-x64 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/bin/ossiq/_internal/Python.framework/Versions/3.13/Python +0 -0
- package/bin/ossiq/_internal/Python.framework/Versions/3.13/Resources/Info.plist +30 -0
- package/bin/ossiq/_internal/attrs-26.1.0.dist-info/INSTALLER +1 -0
- package/bin/ossiq/_internal/attrs-26.1.0.dist-info/METADATA +199 -0
- package/bin/ossiq/_internal/attrs-26.1.0.dist-info/RECORD +37 -0
- package/bin/ossiq/_internal/attrs-26.1.0.dist-info/REQUESTED +0 -0
- package/bin/ossiq/_internal/attrs-26.1.0.dist-info/WHEEL +4 -0
- package/bin/ossiq/_internal/attrs-26.1.0.dist-info/licenses/LICENSE +21 -0
- package/bin/ossiq/_internal/base_library.zip +0 -0
- package/bin/ossiq/_internal/cel/cel.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/certifi/cacert.pem +3959 -0
- package/bin/ossiq/_internal/certifi/py.typed +0 -0
- package/bin/ossiq/_internal/charset_normalizer/cd.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/charset_normalizer/md.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/common_expression_language-0.10.0.dist-info/INSTALLER +1 -0
- package/bin/ossiq/_internal/common_expression_language-0.10.0.dist-info/METADATA +261 -0
- package/bin/ossiq/_internal/common_expression_language-0.10.0.dist-info/RECORD +16 -0
- package/bin/ossiq/_internal/common_expression_language-0.10.0.dist-info/REQUESTED +0 -0
- package/bin/ossiq/_internal/common_expression_language-0.10.0.dist-info/WHEEL +4 -0
- package/bin/ossiq/_internal/common_expression_language-0.10.0.dist-info/entry_points.txt +2 -0
- package/bin/ossiq/_internal/common_expression_language-0.10.0.dist-info/licenses/LICENSE +201 -0
- package/bin/ossiq/_internal/common_expression_language-0.10.0.dist-info/sboms/cel.cyclonedx.json +2109 -0
- package/bin/ossiq/_internal/libcrypto.3.dylib +0 -0
- package/bin/ossiq/_internal/libncurses.6.dylib +0 -0
- package/bin/ossiq/_internal/libssl.3.dylib +0 -0
- package/bin/ossiq/_internal/ossiq/data/SKILL.md +313 -0
- package/bin/ossiq/_internal/ossiq/domain/README.md +373 -0
- package/bin/ossiq/_internal/ossiq/solver/README.md +155 -0
- package/bin/ossiq/_internal/ossiq/strategy/README.md +182 -0
- package/bin/ossiq/_internal/ossiq/ui/html_templates/filter_format_highlight_days.html +7 -0
- package/bin/ossiq/_internal/ossiq/ui/html_templates/spa_app.html +18125 -0
- package/bin/ossiq/_internal/ossiq/ui/html_templates/tag_versions_difference.html +33 -0
- package/bin/ossiq/_internal/ossiq/ui/renderers/export/README.md +207 -0
- package/bin/ossiq/_internal/ossiq/ui/renderers/export/schemas/export_schema_v1.5.json +1637 -0
- package/bin/ossiq/_internal/ossiq/ui/renderers/export/schemas/export_schema_v1.5_standard.json +1164 -0
- package/bin/ossiq/_internal/ossiq-0.1.12.dist-info/INSTALLER +1 -0
- package/bin/ossiq/_internal/ossiq-0.1.12.dist-info/METADATA +385 -0
- package/bin/ossiq/_internal/ossiq-0.1.12.dist-info/RECORD +13 -0
- package/bin/ossiq/_internal/ossiq-0.1.12.dist-info/REQUESTED +0 -0
- package/bin/ossiq/_internal/ossiq-0.1.12.dist-info/WHEEL +4 -0
- package/bin/ossiq/_internal/ossiq-0.1.12.dist-info/direct_url.json +1 -0
- package/bin/ossiq/_internal/ossiq-0.1.12.dist-info/entry_points.txt +2 -0
- package/bin/ossiq/_internal/ossiq-0.1.12.dist-info/licenses/AUTHORS +8 -0
- package/bin/ossiq/_internal/ossiq-0.1.12.dist-info/licenses/LICENSE +661 -0
- package/bin/ossiq/_internal/ossiq-0.1.12.dist-info/uv_build.json +1 -0
- package/bin/ossiq/_internal/ossiq-0.1.12.dist-info/uv_cache.json +1 -0
- package/bin/ossiq/_internal/prompt_toolkit-3.0.53.dist-info/INSTALLER +1 -0
- package/bin/ossiq/_internal/prompt_toolkit-3.0.53.dist-info/METADATA +171 -0
- package/bin/ossiq/_internal/prompt_toolkit-3.0.53.dist-info/RECORD +154 -0
- package/bin/ossiq/_internal/prompt_toolkit-3.0.53.dist-info/REQUESTED +0 -0
- package/bin/ossiq/_internal/prompt_toolkit-3.0.53.dist-info/WHEEL +5 -0
- package/bin/ossiq/_internal/prompt_toolkit-3.0.53.dist-info/licenses/AUTHORS.rst +11 -0
- package/bin/ossiq/_internal/prompt_toolkit-3.0.53.dist-info/licenses/LICENSE +27 -0
- package/bin/ossiq/_internal/prompt_toolkit-3.0.53.dist-info/top_level.txt +1 -0
- package/bin/ossiq/_internal/pycard.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/pydantic-2.13.5.dist-info/INSTALLER +1 -0
- package/bin/ossiq/_internal/pydantic-2.13.5.dist-info/METADATA +1307 -0
- package/bin/ossiq/_internal/pydantic-2.13.5.dist-info/RECORD +113 -0
- package/bin/ossiq/_internal/pydantic-2.13.5.dist-info/REQUESTED +0 -0
- package/bin/ossiq/_internal/pydantic-2.13.5.dist-info/WHEEL +4 -0
- package/bin/ossiq/_internal/pydantic-2.13.5.dist-info/licenses/LICENSE +21 -0
- package/bin/ossiq/_internal/pydantic_core/_pydantic_core.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/pyformula.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/pysolvers.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_asyncio.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_bisect.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_blake2.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_bz2.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_codecs_cn.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_codecs_hk.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_codecs_iso2022.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_codecs_jp.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_codecs_kr.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_codecs_tw.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_contextvars.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_csv.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_ctypes.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_curses.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_datetime.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_decimal.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_hashlib.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_heapq.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_json.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_lzma.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_md5.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_multibytecodec.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_multiprocessing.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_opcode.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_pickle.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_posixshmem.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_posixsubprocess.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_queue.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_random.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_scproxy.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_sha1.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_sha2.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_sha3.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_socket.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_sqlite3.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_ssl.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_statistics.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_struct.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_uuid.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/_zoneinfo.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/array.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/binascii.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/fcntl.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/grp.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/math.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/mmap.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/pyexpat.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/readline.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/resource.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/select.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/syslog.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/termios.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/unicodedata.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/python3.13/lib-dynload/zlib.cpython-313-darwin.so +0 -0
- package/bin/ossiq/_internal/semantic_version-2.10.0.dist-info/INSTALLER +1 -0
- package/bin/ossiq/_internal/semantic_version-2.10.0.dist-info/LICENSE +22 -0
- package/bin/ossiq/_internal/semantic_version-2.10.0.dist-info/METADATA +324 -0
- package/bin/ossiq/_internal/semantic_version-2.10.0.dist-info/RECORD +10 -0
- package/bin/ossiq/_internal/semantic_version-2.10.0.dist-info/REQUESTED +0 -0
- package/bin/ossiq/_internal/semantic_version-2.10.0.dist-info/WHEEL +6 -0
- package/bin/ossiq/_internal/semantic_version-2.10.0.dist-info/top_level.txt +1 -0
- package/bin/ossiq/_internal/setuptools/_vendor/jaraco/text/Lorem ipsum.txt +2 -0
- package/bin/ossiq/_internal/wcwidth/py.typed +0 -0
- package/bin/ossiq/_internal/wcwidth/textwrap.py,cover +664 -0
- package/bin/ossiq/_internal/yaml/_yaml.cpython-313-darwin.so +0 -0
- package/bin/ossiq/ossiq +0 -0
- package/package.json +24 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ossiq-dependency-check
|
|
3
|
+
description: >-
|
|
4
|
+
Check open-source dependency health with OSS IQ before adding a new dependency
|
|
5
|
+
or updating existing ones. Use whenever you are about to add a package to a
|
|
6
|
+
project (pip/uv/npm install, editing pyproject.toml / package.json) or bump
|
|
7
|
+
dependency versions. Returns a per-package `next_action` (what to do next), a
|
|
8
|
+
recommended version, known CVEs, and supply-chain warnings.
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# OSS IQ dependency check
|
|
12
|
+
|
|
13
|
+
OSS IQ is a **local CLI tool** — it runs entirely on your machine and does not
|
|
14
|
+
send any project data to external services. All analysis is performed locally.
|
|
15
|
+
|
|
16
|
+
Run via `uvx ossiq` (no install needed, works from any directory) or bare `ossiq` if already installed.
|
|
17
|
+
|
|
18
|
+
**GitHub rate limits:** Without a token, GitHub's API allows 60 req/hr. If you hit rate limits, the user should run `ossiq install skills <tool> --github-token <token>` once to store the token in `~/.ossiq/config` (classic PAT, no scopes needed for public repos raises the limit to 5 000 req/hr). Do not ask the user to pass it manually on every command.
|
|
19
|
+
|
|
20
|
+
OSS IQ scores dependency health: drift, CVEs, maintainer/bus-factor risk,
|
|
21
|
+
typosquat signals, and a solver-recommended version. Run it **before** you
|
|
22
|
+
change a project's dependencies and do what the `next_action` says.
|
|
23
|
+
|
|
24
|
+
Either call the CLI (below) or, if an MCP server named `ossiq` is connected, call
|
|
25
|
+
the equivalent tools `ossiq_evaluate_dependency` / `ossiq_evaluate_updates`. Prefer these (or
|
|
26
|
+
`--format agent`). If you need a file to hand over instead, `ossiq export` writes the standard
|
|
27
|
+
profile - every direct dependency, the transitives that need attention, decision fields only.
|
|
28
|
+
`ossiq export --full` adds every transitive, the dependency tree and raw upstream signals; it is for
|
|
29
|
+
dashboards and archives and several times larger, so don't feed it to an agent.
|
|
30
|
+
|
|
31
|
+
## Tell OSS IQ which runtime the project runs on
|
|
32
|
+
|
|
33
|
+
Recommendations depend on the runtime (which Node can `require()` an ESM-only package, which
|
|
34
|
+
Python a release supports). Don't let OSS IQ guess it:
|
|
35
|
+
|
|
36
|
+
- **MCP:** every tool **requires** `runtime`, keyed by the project's registry:
|
|
37
|
+
`{"node": "22.12.0"}` for npm, `{"python": "3.11"}` for PyPI. Take the version from the same
|
|
38
|
+
shell that runs the project's own tests: `node -v` next to `npm test`, `python --version` inside
|
|
39
|
+
the project's environment. If you can't tell, pass `"unknown"`; OSS IQ then assumes no runtime
|
|
40
|
+
beyond the project's declared floor. **Never guess a version.**
|
|
41
|
+
- **CLI:** OSS IQ probes the runtime on `PATH` by default. When that isn't the project's runtime
|
|
42
|
+
(nvm, fnm, volta, a different venv), pass `--engine node=<version>` / `--engine python=<version>`.
|
|
43
|
+
|
|
44
|
+
The runtime you state is still held to the project's declared floor (`engines.node`,
|
|
45
|
+
`requires-python`). If it disagrees with a version pin the project keeps (`.nvmrc`,
|
|
46
|
+
`.node-version`, `.tool-versions`, `mise.toml`, `volta.node`, `.python-version`, `.venv`),
|
|
47
|
+
`runtime_context.runtime_mismatch` says so. Re-check which shell you read the version from.
|
|
48
|
+
|
|
49
|
+
## When adding a new dependency
|
|
50
|
+
|
|
51
|
+
Before introducing a package, run:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
uvx ossiq info <package> <project_path> --format agent
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Example output:
|
|
58
|
+
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"operation": "add",
|
|
62
|
+
"registry": "pypi",
|
|
63
|
+
"package": "requests",
|
|
64
|
+
"next_action": "install with caution",
|
|
65
|
+
"recommended_version": "2.31.0",
|
|
66
|
+
"latest_in_range": null,
|
|
67
|
+
"latest_in_major": null,
|
|
68
|
+
"reasons": ["recommend 2.31.0 rather than latest 2.32.0", "single maintainer — bus factor risk"],
|
|
69
|
+
"cves": [],
|
|
70
|
+
"warnings": ["SINGLE_MAINTAINER"]
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
`latest_in_range`/`latest_in_major` are only populated for a package already
|
|
75
|
+
installed in the project (not a prospective add) — see the version ladder below.
|
|
76
|
+
|
|
77
|
+
`next_action` for an add is `install`, `install with caution`, or `do not install`.
|
|
78
|
+
|
|
79
|
+
## When updating existing dependencies
|
|
80
|
+
|
|
81
|
+
Before bumping versions, run:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
uvx ossiq status <project_path> --format agent
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
By default this targets the `standard` tier of the update pyramid (plain drift, inside each
|
|
88
|
+
package's declared range). Pass `--update-strategy security` for the smallest diff that clears
|
|
89
|
+
known CVEs, or `latest`/`cutting-edge` to also widen constraints / admit prereleases — see
|
|
90
|
+
`ossiq status --help`. The MCP tool `ossiq_evaluate_updates` takes the same `update_strategy`
|
|
91
|
+
argument.
|
|
92
|
+
|
|
93
|
+
Example output:
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"operation": "update",
|
|
98
|
+
"registry": "npm",
|
|
99
|
+
"update_strategy": "standard",
|
|
100
|
+
"next_action": "Check for the Fix",
|
|
101
|
+
"updates": [
|
|
102
|
+
{
|
|
103
|
+
"package": "lodash",
|
|
104
|
+
"next_action": "Check for the Fix",
|
|
105
|
+
"from": "4.17.15",
|
|
106
|
+
"to": "4.17.21",
|
|
107
|
+
"latest_in_range": "4.17.15",
|
|
108
|
+
"latest_in_major": "4.17.21",
|
|
109
|
+
"reasons": ["CVE-2021-23337 (HIGH)", "recommend updating 4.17.15 -> 4.17.21"],
|
|
110
|
+
"cves": [{"id": "CVE-2021-23337", "severity": "HIGH", "summary": "...", "epss": 0.2133, "fixed_in": ["4.17.21"]}],
|
|
111
|
+
"transitive_impact": []
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"package": "pydantic",
|
|
115
|
+
"next_action": "Constrained. Check newer version",
|
|
116
|
+
"from": "1.10.13",
|
|
117
|
+
"to": "1.10.26",
|
|
118
|
+
"latest_in_range": "1.10.13",
|
|
119
|
+
"latest_in_major": "1.10.26",
|
|
120
|
+
"requires_constraint_widening": true,
|
|
121
|
+
"reasons": [
|
|
122
|
+
"declared range ==1.10.13 caps this below 2.13.5",
|
|
123
|
+
"declared range ==1.10.13 must be widened to reach 1.10.26"
|
|
124
|
+
],
|
|
125
|
+
"cves": [],
|
|
126
|
+
"transitive_impact": []
|
|
127
|
+
}
|
|
128
|
+
]
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
The top-level `next_action` is the most urgent one across the `updates` list, or
|
|
133
|
+
`no action needed` when the list is empty. Each entry's `next_action` is one of:
|
|
134
|
+
|
|
135
|
+
- **Check for the Fix** — a known CVE that `to` does not clear (or there is no `to`); check for a
|
|
136
|
+
patched release.
|
|
137
|
+
- **Find alternative** — the package is gone or its upstream is abandoned/deprecated; migrate off it.
|
|
138
|
+
- **Consider alternative** — the upstream is winding down; plan a migration.
|
|
139
|
+
- **Check Release Notes** — a major version behind; review breaking changes before the bump.
|
|
140
|
+
- **Update Immediately** — a minor/patch behind, or a recommended version exists; bump it.
|
|
141
|
+
- **Constrained. Check newer version** — a minor/patch behind, but the declared range
|
|
142
|
+
(e.g. `~7.3.0`) admits no newer version, or the CVE fix in `to` needs it widened; widening the
|
|
143
|
+
range is the real next step.
|
|
144
|
+
- **Withheld by strategy** — a minor/patch behind, and the range admits a bump, but the run's
|
|
145
|
+
`--update-strategy` tier admitted no motive to take it. Nothing is wrong with the package;
|
|
146
|
+
`strategy_withheld_reason` names the lowest tier that would move it.
|
|
147
|
+
|
|
148
|
+
`latest_in_range` (newest version satisfying the declared constraint) and
|
|
149
|
+
`latest_in_major` (newest version sharing the installed major line) are always
|
|
150
|
+
present — equal to `from` when that step has nothing newer, never omitted.
|
|
151
|
+
|
|
152
|
+
`dependency_health` (when present) is **advice, not the action**. It answers "is this dependency
|
|
153
|
+
healthy long-term?" (`retain` / `patch` / `refactor` / `evict`, from exploit probability ×
|
|
154
|
+
upstream maintenance). `next_action` is what to do now. A `retain` next to a CVE doesn't mean
|
|
155
|
+
"don't update": `suppressed_cves` counts CVEs scored below the EPSS noise floor, and each CVE's
|
|
156
|
+
own `epss` is listed under `cves`.
|
|
157
|
+
|
|
158
|
+
Each CVE's `fixed_in` lists the releases that close it, one per fixed line (uuid's
|
|
159
|
+
GHSA-w5hq-g745-h8pq: `["11.1.1", "12.0.1", "13.0.1"]` - so 12.0.0 is still affected). If you pick
|
|
160
|
+
a target other than `to`, check it against `fixed_in`, or ask `update_context` for its verdict;
|
|
161
|
+
don't bisect the release history one version at a time.
|
|
162
|
+
|
|
163
|
+
`dependency_name` appears only when the manifest declares the package under a different key
|
|
164
|
+
than its registry name — npm aliases (`"uuid-v7": "npm:uuid@^7.0.0"`) are the only case today.
|
|
165
|
+
Two aliases of one package produce two entries sharing `"package"`, so `dependency_name` is what
|
|
166
|
+
tells you which declaration an entry answers for and which line to edit.
|
|
167
|
+
|
|
168
|
+
### Module-system and API breaks
|
|
169
|
+
|
|
170
|
+
A recommended version is not always drop-in. Semver alone can't see an npm package going
|
|
171
|
+
ESM-only. For a CommonJS project (no `"type": "module"`), OSS IQ keeps `to` on the installed
|
|
172
|
+
module system:
|
|
173
|
+
|
|
174
|
+
- `security`, `deprecation` and `standard` never recommend an ESM-only release. When every newer
|
|
175
|
+
release is ESM-only and the only reason to move is drift, `to` equals `from`, and
|
|
176
|
+
`rejected_candidates`/`reasons` say `"<version> rejected: ESM-only from 5.0.0"`.
|
|
177
|
+
- `latest` and `cutting-edge` may recommend an ESM-only release, but only when the stated runtime
|
|
178
|
+
can `require()` ESM (Node ≥ 20.19 / ≥ 22.12 / ≥ 23). The pick then carries `breaking_change`
|
|
179
|
+
and `carries_known_break: true`.
|
|
180
|
+
- **Exception:** when a CVE (or end-of-life) has no fix left on the CommonJS line, the ESM-only
|
|
181
|
+
fix is recommended at every tier, flagged the same way. Security beats build convenience.
|
|
182
|
+
|
|
183
|
+
```json
|
|
184
|
+
{
|
|
185
|
+
"package": "chalk",
|
|
186
|
+
"next_action": "Check Release Notes",
|
|
187
|
+
"from": "4.0.0",
|
|
188
|
+
"to": "4.1.2",
|
|
189
|
+
"latest_in_major": "4.1.2",
|
|
190
|
+
"latest_compatible_major": "6.0.0",
|
|
191
|
+
"latest_preserving_module_system": "4.1.2",
|
|
192
|
+
"module_system": "cjs",
|
|
193
|
+
"recommended_module_system": "cjs",
|
|
194
|
+
"breaking_change": null,
|
|
195
|
+
"module_system_note": "ESM-only: require() on Node 22.12.0 returns the module namespace, so it works only if the package has named exports; a default-export-only package still breaks",
|
|
196
|
+
"reasons": ["major version drift behind 6.0.0", "5.6.2 rejected: ESM-only from 5.0.0"]
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
- `latest_preserving_module_system` is the newest release your code can keep loading as it
|
|
201
|
+
does today, whatever the runtime.
|
|
202
|
+
- `latest_compatible_major` is the newest release the stated runtime *might* load.
|
|
203
|
+
- `module_system_note` explains the gap between the two. `require()` of an ESM-only package
|
|
204
|
+
returns its namespace, so `const { v4 } = require("uuid")` works on a capable Node, but
|
|
205
|
+
`require("chalk").bold` does not, because chalk only has a default export.
|
|
206
|
+
|
|
207
|
+
Whenever `breaking_change` is non-null, don't treat `to` as safe to `require()` until the
|
|
208
|
+
project's own tests pass on it.
|
|
209
|
+
|
|
210
|
+
Pin to `recommended_version` (`to`) when it is set — it is the solver's safe
|
|
211
|
+
choice (avoids known-CVE and too-fresh versions) — **unless the entry also carries
|
|
212
|
+
`"requires_constraint_widening": true`**. That flag means `to` is only reachable by
|
|
213
|
+
widening the manifest's declared range first (`==1.10.13` admits nothing past
|
|
214
|
+
1.10.13, so `1.10.26` needs a wider specifier, not just a straight rewrite of the
|
|
215
|
+
pin). `ossiq update`/`ossiq apply` will not write such an entry on their own —
|
|
216
|
+
widen the constraint by hand, then re-run the command.
|
|
217
|
+
|
|
218
|
+
### Engine/runtime compatibility
|
|
219
|
+
|
|
220
|
+
`to` also routes around a package version whose declared runtime requirement (npm `engines.node`,
|
|
221
|
+
PyPI `requires-python`) conflicts with the runtime actually checked, the same way it routes around
|
|
222
|
+
a module-system break — `engine_requirement`/`engine_compatible`/`engine_context_source` report the
|
|
223
|
+
result for whichever version `to` ended up being:
|
|
224
|
+
|
|
225
|
+
```json
|
|
226
|
+
{
|
|
227
|
+
"package": "some-pkg",
|
|
228
|
+
"to": "1.1.0",
|
|
229
|
+
"engine_requirement": {"node": ">=16.0.0"},
|
|
230
|
+
"engine_compatible": true,
|
|
231
|
+
"engine_context_source": "detected",
|
|
232
|
+
"reasons": []
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
`engine_compatible` is checked against the **lower** of two versions per engine: the runtime (the
|
|
237
|
+
one you stated, or, on the CLI, the one probed on this machine) and the project's own manifest floor (`engines.node`/`requires-python`). The
|
|
238
|
+
floor counts even when a newer runtime is installed, because a release that outruns it breaks the
|
|
239
|
+
project's own users and will fail resolution — `uv` resolves every Python version in the declared
|
|
240
|
+
range, not just the one you are on. `engine_context_source` says which side is binding:
|
|
241
|
+
`"provided"` (the runtime you stated, for every engine), `"detected"` (the CLI probe, for every
|
|
242
|
+
engine), `"declared"` (the manifest floor, for at least one), or `"none"` — neither was available, and `engine_compatible` is `null` in that case, absence of
|
|
243
|
+
evidence rather than evidence of compatibility. When every reachable version conflicts, `to` still
|
|
244
|
+
lands on the newest one and `engine_compatible: false` names the concrete requirement and the
|
|
245
|
+
version it was checked against instead of leaving it a silent runtime failure.
|
|
246
|
+
|
|
247
|
+
## Before applying an update to a specific version
|
|
248
|
+
|
|
249
|
+
`to` above is OSS IQ's own recommendation. If you (or the user) want to go to a *different*
|
|
250
|
+
version — one `ossiq status`/`ossiq_evaluate_updates` didn't propose — check it first instead of
|
|
251
|
+
discovering a break via test failure:
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
uvx ossiq update-context <package> <project_path> --to <version>
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
or, over MCP, `ossiq_update_context` with `{"package": ..., "target_version": ..., "runtime": ...}`. `target_version`
|
|
258
|
+
is optional and defaults to the recommended version, so the same call also works as "explain the
|
|
259
|
+
recommendation in detail" with no `--to` at all.
|
|
260
|
+
|
|
261
|
+
Example — asking about `chalk 6.0.0` on a CommonJS project that's currently on `4.1.2`:
|
|
262
|
+
|
|
263
|
+
```json
|
|
264
|
+
{
|
|
265
|
+
"package": "chalk",
|
|
266
|
+
"registry": "npm",
|
|
267
|
+
"from_version": "4.1.2",
|
|
268
|
+
"to_version": "6.0.0",
|
|
269
|
+
"module_system": {"from": "cjs", "to": "esm-only", "project_declares_esm": false},
|
|
270
|
+
"comparison": {
|
|
271
|
+
"verdict": "breaking",
|
|
272
|
+
"reasons": ["6.0.0 crosses a known break: ESM-only from 6.0.0"],
|
|
273
|
+
"recommended_version": "4.1.2",
|
|
274
|
+
"better_available": "4.1.2"
|
|
275
|
+
},
|
|
276
|
+
"breaking_change": "ESM-only from 6.0.0",
|
|
277
|
+
"module_system_note": "ESM-only: won't load via require() on Node 20.11.0",
|
|
278
|
+
"latest_compatible_major": "4.1.2",
|
|
279
|
+
"engine": {
|
|
280
|
+
"requirement": {"node": ">=20.19.0"},
|
|
281
|
+
"context_version": "20.11.0",
|
|
282
|
+
"context_source": "provided",
|
|
283
|
+
"compatible": false
|
|
284
|
+
},
|
|
285
|
+
"npm_cli_version": "10.2.4",
|
|
286
|
+
"rejected_candidates": [{"version": "5.0.0", "reason": "ESM-only from 5.0.0"}]
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
**Read `comparison.verdict` first.** It holds the target up against OSS IQ's own recommendation:
|
|
291
|
+
|
|
292
|
+
- `recommended`: it *is* the recommendation.
|
|
293
|
+
- `suboptimal`: clean, but older than the recommendation.
|
|
294
|
+
- `breaking`, `vulnerable`, `deprecated`: the target has that problem. `reasons` lists every
|
|
295
|
+
problem found.
|
|
296
|
+
- `beyond_recommendation`: clean, but past what OSS IQ recommends; check what held the
|
|
297
|
+
recommendation back.
|
|
298
|
+
|
|
299
|
+
Any verdict other than `recommended` means take `better_available` unless you have a reason not
|
|
300
|
+
to. A diff with no `breaking_change` is **not** an approval on its own: a deprecated release older
|
|
301
|
+
than the recommendation has none.
|
|
302
|
+
|
|
303
|
+
This says: going to `6.0.0` hits the same ESM-only break as `5.0.0` (`module_system.to`), and
|
|
304
|
+
separately its `engines.node` requirement (`>=20.19.0`) is newer than what's actually installed
|
|
305
|
+
locally (`20.11.0`) — two independent reasons this specific version is risky, neither of which
|
|
306
|
+
`recommended_version` alone would have surfaced for an arbitrary target. `latest_compatible_major`
|
|
307
|
+
(`4.1.2`) is where `recommended_version` would fall back to instead. `rejected_candidates` lists
|
|
308
|
+
versions at or below the requested target that a normal scan already rejected along the way — use
|
|
309
|
+
it for "what else already failed on the path here", not as an exhaustive audit of every release.
|
|
310
|
+
|
|
311
|
+
For a package not yet installed, `from_version` is `null` and the payload otherwise has the same
|
|
312
|
+
shape — useful for previewing a brand-new dependency's own module-system/engine story before
|
|
313
|
+
adding it.
|