@ossiq/cli-darwin-arm64 0.1.12 → 0.1.14

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.
Files changed (58) hide show
  1. package/bin/ossiq/_internal/Python +0 -0
  2. package/bin/ossiq/_internal/Python.framework/Python +0 -0
  3. package/bin/ossiq/_internal/Python.framework/Resources/Info.plist +30 -0
  4. package/bin/ossiq/_internal/Python.framework/Versions/Current/Python +0 -0
  5. package/bin/ossiq/_internal/Python.framework/Versions/Current/Resources/Info.plist +30 -0
  6. package/bin/ossiq/_internal/base_library.zip +0 -0
  7. package/bin/ossiq/_internal/keyring-25.7.0.dist-info/METADATA +554 -0
  8. package/bin/ossiq/_internal/keyring-25.7.0.dist-info/RECORD +40 -0
  9. package/bin/ossiq/_internal/{semantic_version-2.10.0.dist-info → keyring-25.7.0.dist-info}/WHEEL +1 -2
  10. package/bin/ossiq/_internal/keyring-25.7.0.dist-info/entry_points.txt +13 -0
  11. package/bin/ossiq/_internal/keyring-25.7.0.dist-info/licenses/LICENSE +18 -0
  12. package/bin/ossiq/_internal/keyring-25.7.0.dist-info/top_level.txt +1 -0
  13. package/bin/ossiq/_internal/lark/grammars/common.lark +59 -0
  14. package/bin/ossiq/_internal/lark/grammars/lark.lark +62 -0
  15. package/bin/ossiq/_internal/lark/grammars/python.lark +302 -0
  16. package/bin/ossiq/_internal/lark/grammars/unicode.lark +7 -0
  17. package/bin/ossiq/_internal/ossiq/data/SKILL.md +42 -16
  18. package/bin/ossiq/_internal/ossiq/domain/README.md +30 -4
  19. package/bin/ossiq/_internal/ossiq/solver/README.md +10 -3
  20. package/bin/ossiq/_internal/ossiq/strategy/README.md +20 -2
  21. package/bin/ossiq/_internal/ossiq/ui/html_templates/spa_app.html +1828 -1518
  22. package/bin/ossiq/_internal/ossiq/ui/renderers/export/README.md +103 -40
  23. package/bin/ossiq/_internal/ossiq/ui/renderers/export/schemas/export_schema_v1.6.json +1805 -0
  24. package/bin/ossiq/_internal/ossiq/ui/renderers/export/schemas/export_schema_v1.6_standard.json +1328 -0
  25. package/bin/ossiq/_internal/ossiq-0.1.14.dist-info/METADATA +207 -0
  26. package/bin/ossiq/_internal/ossiq-0.1.14.dist-info/RECORD +13 -0
  27. package/bin/ossiq/_internal/ossiq-0.1.14.dist-info/REQUESTED +0 -0
  28. package/bin/ossiq/_internal/ossiq-0.1.14.dist-info/uv_cache.json +1 -0
  29. package/bin/ossiq/_internal/pycard.cpython-313-darwin.so +0 -0
  30. package/bin/ossiq/_internal/pyformula.cpython-313-darwin.so +0 -0
  31. package/bin/ossiq/_internal/pysolvers.cpython-313-darwin.so +0 -0
  32. package/bin/ossiq/_internal/setuptools/_vendor/importlib_metadata-8.7.1.dist-info/INSTALLER +1 -0
  33. package/bin/ossiq/_internal/setuptools/_vendor/importlib_metadata-8.7.1.dist-info/METADATA +133 -0
  34. package/bin/ossiq/_internal/setuptools/_vendor/importlib_metadata-8.7.1.dist-info/RECORD +21 -0
  35. package/bin/ossiq/_internal/setuptools/_vendor/importlib_metadata-8.7.1.dist-info/REQUESTED +0 -0
  36. package/bin/ossiq/_internal/setuptools/_vendor/importlib_metadata-8.7.1.dist-info/WHEEL +5 -0
  37. package/bin/ossiq/_internal/setuptools/_vendor/importlib_metadata-8.7.1.dist-info/licenses/LICENSE +73 -0
  38. package/bin/ossiq/_internal/setuptools/_vendor/importlib_metadata-8.7.1.dist-info/top_level.txt +1 -0
  39. package/bin/ossiq/ossiq +0 -0
  40. package/package.json +1 -1
  41. package/bin/ossiq/_internal/ossiq-0.1.12.dist-info/METADATA +0 -385
  42. package/bin/ossiq/_internal/ossiq-0.1.12.dist-info/RECORD +0 -13
  43. package/bin/ossiq/_internal/ossiq-0.1.12.dist-info/uv_cache.json +0 -1
  44. package/bin/ossiq/_internal/semantic_version-2.10.0.dist-info/LICENSE +0 -22
  45. package/bin/ossiq/_internal/semantic_version-2.10.0.dist-info/METADATA +0 -324
  46. package/bin/ossiq/_internal/semantic_version-2.10.0.dist-info/RECORD +0 -10
  47. package/bin/ossiq/_internal/semantic_version-2.10.0.dist-info/top_level.txt +0 -1
  48. package/bin/ossiq/_internal/wcwidth/textwrap.py,cover +0 -664
  49. /package/bin/ossiq/_internal/{ossiq-0.1.12.dist-info → keyring-25.7.0.dist-info}/INSTALLER +0 -0
  50. /package/bin/ossiq/_internal/{ossiq-0.1.12.dist-info → keyring-25.7.0.dist-info}/REQUESTED +0 -0
  51. /package/bin/ossiq/_internal/{semantic_version-2.10.0.dist-info/REQUESTED → lark/py.typed} +0 -0
  52. /package/bin/ossiq/_internal/{semantic_version-2.10.0.dist-info → ossiq-0.1.14.dist-info}/INSTALLER +0 -0
  53. /package/bin/ossiq/_internal/{ossiq-0.1.12.dist-info → ossiq-0.1.14.dist-info}/WHEEL +0 -0
  54. /package/bin/ossiq/_internal/{ossiq-0.1.12.dist-info → ossiq-0.1.14.dist-info}/direct_url.json +0 -0
  55. /package/bin/ossiq/_internal/{ossiq-0.1.12.dist-info → ossiq-0.1.14.dist-info}/entry_points.txt +0 -0
  56. /package/bin/ossiq/_internal/{ossiq-0.1.12.dist-info → ossiq-0.1.14.dist-info}/licenses/AUTHORS +0 -0
  57. /package/bin/ossiq/_internal/{ossiq-0.1.12.dist-info → ossiq-0.1.14.dist-info}/licenses/LICENSE +0 -0
  58. /package/bin/ossiq/_internal/{ossiq-0.1.12.dist-info → ossiq-0.1.14.dist-info}/uv_build.json +0 -0
@@ -12,7 +12,9 @@ This document lists the external specifications that define or inform the domain
12
12
 
13
13
  | Field | Registry | Meaning |
14
14
  |-------|----------|---------|
15
- | `is_deprecated: bool` | npm | The package's latest version carries a `deprecated` field — the whole package is considered deprecated. Set via `npm deprecate <pkg>`. |
15
+ | `registry_status: RegistryStatus \| None` | npm / PyPI | The registry's verdict on the whole package, in PEP 792's vocabulary: `active`, `deprecated`, `archived`, `quarantined`. npm: `deprecated` when `versions[latest].deprecated` is set (via `npm deprecate <pkg>`), else `active`. PyPI: the Simple API's project status. `None` when the registry gave none, which is not `active`. |
16
+ | `is_deprecated: bool` | npm / PyPI | Read-only, derived from `registry_status`: true for `deprecated` and `archived`. `quarantined` is an administrator's safety verdict, not a maintainer's decision, so it does not count. |
17
+ | `deprecation_message: str \| None` | npm / PyPI | npm's `deprecated` note on the latest version, or PyPI's PEP 792 reason. |
16
18
  | `is_unpublished: bool` | npm | `time.unpublished` is present in the packument — the entire package was removed from the registry. |
17
19
  | `canonical_name: str \| None` | npm | When a package is installed under an npm alias (e.g. `"chalk-legacy": "npm:chalk@4"`), `name` is the alias and `canonical_name` is the real registry name used for lookups. `None` when `name` already is the canonical registry name. |
18
20
 
@@ -20,7 +22,8 @@ This document lists the external specifications that define or inform the domain
20
22
 
21
23
  | Field | Registry | Meaning |
22
24
  |-------|----------|---------|
23
- | `is_deprecated: bool` | npm | This specific version's manifest has a truthy `deprecated` field. |
25
+ | `is_deprecated: bool` | npm | This specific version's manifest has a truthy `deprecated` field. PyPI has no per-release deprecation; a yanked release is its equivalent. |
26
+ | `deprecation_message: str \| None` | npm | The `deprecated` note on this version. |
24
27
  | `is_yanked: bool` | PyPI | The version exists on PyPI but is marked yanked — excluded from normal resolution. |
25
28
  | `is_unpublished: bool` | npm | The version was individually deleted after release (present in `time` but absent from `versions`), or the entire package was unpublished (all versions inherit this flag). |
26
29
  | `is_prerelease: bool` | npm / PyPI | Version string contains a pre-release segment (e.g. `alpha`, `beta`, `rc`, `dev`). Set by registry adapters during version list construction. |
@@ -34,9 +37,11 @@ This document lists the external specifications that define or inform the domain
34
37
  | `is_installed_prerelease` | `version.is_prerelease` | Installed version is a pre-release. |
35
38
  | `is_installed_yanked` | `version.is_yanked or version.is_unpublished` | Installed version was pulled from the registry (covers both PyPI yanked and npm unpublished). |
36
39
  | `is_installed_deprecated` | `version.is_deprecated or package.is_deprecated` | Installed version or its parent package is deprecated. |
40
+ | `registry_status` | `package.registry_status` | The registry's verdict on the whole package. Unlike `is_installed_deprecated`, a deprecated release of an otherwise live package does not show here. |
41
+ | `deprecation_message` | `package.deprecation_message`, else the installed version's | The note behind the deprecation. |
37
42
  | `is_installed_package_unpublished` | `package.is_unpublished` | The entire package has been removed from the registry. |
38
43
 
39
- Display priority in all renderers: **UNPUBLISHED** > **YANKED** > **DEPRECATED** > pre-release.
44
+ Display priority in all renderers: **UNPUBLISHED** > **YANKED** > **QUARANTINED** > **ARCHIVED** > **DEPRECATED** > pre-release.
40
45
 
41
46
  ---
42
47
 
@@ -126,6 +131,9 @@ Priority ordering for display: **OVERRIDE** > **ADDITIVE** > **PINNED** > **NARR
126
131
  | `type` | `ConstraintType` | Classification of the constraint (see above). |
127
132
  | `source_file` | `str \| None` | The file that declared it (e.g. `"package.json"`, `"pyproject.toml"`). |
128
133
  | `scope_path` | `list[str] \| None` | For npm nested overrides, the path through the dependency tree; `None` for flat constraints. |
134
+ | `is_ossiq_authored` | `bool` | An `OVERRIDE` whose value is still what OSS IQ last wrote (`ossiq:metadata`); `False` for the user's own. |
135
+ | `override_key` | `str \| None` | npm only: the range a version-keyed rule (`foo@^1`) applies to; `None` when it applies to every version. |
136
+ | `override_value` | `str \| None` | npm only: what the matching rule forces — a version, a range or a `$name` reference. |
129
137
 
130
138
  ### `PeerRequirement` — peer constraint tracking
131
139
 
@@ -138,6 +146,16 @@ Priority ordering for display: **OVERRIDE** > **ADDITIVE** > **PINNED** > **NARR
138
146
 
139
147
  Violations (installed version not satisfying `spec`) are surfaced in `ScanRecord.peer_violations`.
140
148
 
149
+ ### `IncomingEdge` and `InstalledCopy` — who asked for which copy
150
+
151
+ npm installs the same name at several versions (nested `node_modules`), so a package is not one node with a pile of constraints but several copies, each with its own requirers.
152
+
153
+ `IncomingEdge` (in `project.py`) is one parent's requirement on an installed package: `requirer_name`, `requirer_version`, `spec` and `is_peer`. `Dependency.parent_edges` holds them next to `parent_constraints`, which remains the flat spec list the solver reads.
154
+
155
+ `InstalledCopy` (in `project.py`) is one physical copy: its `version`, the `edges` that resolve to it, and its own `constraint_info`. `ScanRecord.installed_copies` lists every copy newest first; `installed_version` is the first. Under pip and uv there is always exactly one.
156
+
157
+ The npm lockfile graph attaches each edge to the copy Node would resolve for that parent — the parent's own `node_modules`, then each ancestor's, up to the top level — which is how `package-lock.json` v2/v3 lays the tree out.
158
+
141
159
  ---
142
160
 
143
161
  ## Dependency Categories
@@ -285,6 +303,14 @@ Key response fields used:
285
303
 
286
304
  `yanked` maps to `PackageVersion.is_yanked`. A yanked version still exists on PyPI but is excluded from normal resolution; pip will refuse to install it unless the version is pinned exactly.
287
305
 
306
+ ### PyPI Simple API (PEP 792 project status)
307
+ **Spec**: https://packaging.python.org/en/latest/specifications/project-status-markers/
308
+ **Applies to**: `Package.registry_status`, `Package.deprecation_message`
309
+
310
+ The JSON API above carries no project status. The Simple API does, in the head of each project page: `<meta name="pypi:project-status" content="archived">` and an optional `pypi:project-status-reason`. The statuses are `active`, `deprecated`, `archived` and `quarantined`; an index may omit the tag for an active project, so an absent tag reads as `active`.
311
+
312
+ Endpoint: `https://pypi.org/simple/{name}/` with `Accept: application/vnd.pypi.simple.v1+html`. A page lists every file of the project (numpy's is 2 MB), so the request asks for the first 2 KB with a `Range` header and `Accept-Encoding: identity`; PyPI answers `206`. A failed request leaves `registry_status` as `None`.
313
+
288
314
  ### npm Registry API
289
315
  **Spec**: https://github.com/npm/registry/blob/master/docs/REGISTRY.md
290
316
  **Applies to**: `Package`, `PackageVersion`, `ProjectPackagesRegistry.NPM`
@@ -295,7 +321,7 @@ Key response fields used:
295
321
  - `name`, `description`, `author`, `homepage`, `repository.url`
296
322
  - `versions.{ver}.dependencies`, `versions.{ver}.devDependencies`, `versions.{ver}.peerDependencies`
297
323
  - `versions.{ver}.deprecated` — non-empty string means this version is deprecated → `PackageVersion.is_deprecated`
298
- - `dist-tags.latest` — current latest version; if `versions[latest].deprecated` is set → `Package.is_deprecated`
324
+ - `dist-tags.latest` — current latest version; if `versions[latest].deprecated` is set → `Package.registry_status = DEPRECATED` (else `ACTIVE`), with the note in `Package.deprecation_message`
299
325
  - `time.{ver}` — publish timestamp per version
300
326
  - `time.unpublished` — present when the entire package was unpublished → `Package.is_unpublished`; every version also gets `PackageVersion.is_unpublished=True`
301
327
  - `dist.integrity`, `dist.tarball` — download and verification
@@ -15,6 +15,8 @@ solver/
15
15
  ├── problem.py SolverProblem, CandidateVersion, PackageConstraint
16
16
  ├── universe.py SolvablePool — builds SolverProblem from registry
17
17
  ├── version_matchers.py npm semver + PEP 440 range matching — raw constraint → bool
18
+ ├── npm_range.py npm range grammar (Lark) + node-semver's rewrite rules → comparator sets
19
+ ├── pep508.py Which declared PyPI requirements apply to a project (extras + environment markers)
18
20
  ├── encoder.py ConstraintEncoder — produces EncodedProblem (WCNF)
19
21
  ├── weights.py Constraint weight constants + semver_rank_weight()
20
22
  └── dependencies_solver.py Public API: solve_direct(), solve_transitive()
@@ -51,7 +53,8 @@ deps / transitive_records
51
53
  SolvablePool.build() universe.py
52
54
  – deduplicates by canonical_name (highest ConstraintType priority wins)
53
55
  – fetches candidates from warm registry cache
54
- – filters yanked, unpublished, prerelease (unless allowed)
56
+ – filters yanked, unpublished, prerelease (unless allowed), and deprecated releases when
57
+ allow_deprecated=False (only `ossiq add` choosing a live package passes that)
55
58
  – sorts candidates descending (newest first)
56
59
  – stamps has_cve=True on versions any of the package's CVEs affects (cves_by_package;
57
60
  judged by version_matchers.cve_affects_version, ranges included)
@@ -85,7 +88,7 @@ greedily; the pluggable RC2 driver **minimises** total violated soft cost exactl
85
88
  | L1 | Hard | — | Version outside declared `version_constraint` (PEP 440 or npm semver) |
86
89
  | L2 | Soft-Hard | `W_ENGINE = 100_000` | Engine mismatch (`python`/`node` requirement vs `engine_context`) |
87
90
  | L3 | Soft | `max(80_000 − rank × 5_000, 1_000)` | Semver-rank preference — rank 0 = latest eligible semver |
88
- | L4 | Soft | `W_DEPRECATED = 10_000` | Deprecated flag — penalty on selection |
91
+ | L4 | Soft | `W_DEPRECATED = 10_000` | Deprecated flag — penalty on selection. A deprecated release still wins over a clean one that ranks two or more places below it (2 × 5 000 = 10 000), and the penalty is the same for every candidate when all are deprecated. A caller that must never get a deprecated release passes `allow_deprecated=False`, which removes them before this level applies |
89
92
  | L5 | Hard | — | CVE-affected version |
90
93
  | L6 | Soft-Hard | `W_VERY_FRESH = 100_000` | Published < 7 days ago — both direct and transitive passes |
91
94
  | L7 | — | *(reserved)* | Health score — not implemented |
@@ -116,7 +119,11 @@ Structural clauses per package (encoder):
116
119
 
117
120
  ### Version constraint dispatch (encoder.py)
118
121
 
119
- `version_satisfies_constraint(version, constraint, registry)` (in `version_matchers.py`) dispatches directly to PyPI (PEP 440) or npm (semver) based on the `ProjectPackagesRegistry` passed in — no exception-based fallback. Bare npm versions (e.g. `"14"`) are treated as caret ranges (`^14.0.0`). Unparseable constraints pass through (`True`) — unknown format is never a hard block.
122
+ `version_satisfies_constraint(version, constraint, registry)` (in `version_matchers.py`) dispatches directly to PyPI (PEP 440) or npm (semver) based on the `ProjectPackagesRegistry` passed in — no exception-based fallback. npm ranges go through `npm_range.py` — a Lark grammar for the syntax plus node-semver's own rewrite rules, held to node-semver's verdicts by `tests/solver/node_semver_conformance.json`, so a partial version (`"14"`) is the X-range `14.x` exactly as npm reads it. Unparseable constraints pass through (`True`) — unknown format is never a hard block — and so does a blank one: PyPI publishes an unconstrained requirement as an empty specifier.
123
+
124
+ ### Which requirements apply (pep508.py)
125
+
126
+ A PyPI release declares requirements gated on extras (`oauthlib<4; extra == "socialaccount"`) and on environment markers (`tomli; python_version < "3.11"`). Whether one applies depends on the project, so `RequirementScope` (`domain/`) carries the extras the project enables per package and its Python floor, and `applicable_requirements()` keeps a requirement when its marker holds in at least one environment the project can be installed into — the same stance uv's universal resolution takes. The registry (`package_version_requires`), the candidate `requires` built in `universe.py`, and the enrichment of lockfile edges all read requirements through it; the scan sets the scope once, from the lockfile's `extra = [...]` edges and `requires-python`.
120
127
 
121
128
  ---
122
129
 
@@ -62,7 +62,7 @@ A strategy is not one dial, it is two, kept separate on purpose:
62
62
 
63
63
  | Tier | Base reach | Escalates to `LATEST` when... |
64
64
  |---|---|---|
65
- | `security` | in-range | an admitted motive is `exploitable_cve` (no in-range version clears the CVE) |
65
+ | `security` | in-range | an admitted motive is `exploitable_cve`; the pick leaves the range only when no in-range version clears the CVE |
66
66
  | `deprecation` | in-range | an admitted motive is `exploitable_cve` or `end_of_life` |
67
67
  | `standard` | in-range | same as above |
68
68
  | `latest` | latest | already maximal |
@@ -77,7 +77,7 @@ A strategy is not one dial, it is two, kept separate on purpose:
77
77
  |---|---|---|
78
78
  | `security` | no target (no CVE) | `2.32.0` — nearest CVE-clear version |
79
79
  | `deprecation` | no target | `2.32.0` |
80
- | `standard` | `1.10.13` — pin admits no in-range move | `2.34.2` — newest, already CVE-clear |
80
+ | `standard` | `1.10.26` — newest in the installed major, reported but not written (`requires_widening=True`) | `2.34.2` — newest, already CVE-clear |
81
81
  | `latest` | `2.13.5` — widens the pin, `requires_widening=True` | `2.34.2` |
82
82
  | `cutting-edge` | `2.13.5` (or newer, if a prerelease exists) | `2.34.2` |
83
83
 
@@ -109,6 +109,10 @@ A strategy is not one dial, it is two, kept separate on purpose:
109
109
  - **`escalation`** — set when reach was pushed past the tier's base `MAX_REACH` (a CVE or
110
110
  end-of-life motive escalated it), or when every reachable candidate still carries a qualifying
111
111
  CVE and the newest was picked anyway. Never silently "stay put".
112
+ - **`widening_authorized`** — an escalating motive carried the pick past the tier's base
113
+ `MAX_REACH` and some reachable version clears the CVE. `plan` lists the pick as an update instead
114
+ of holding it under *Requires constraint widening*; `apply` still confirms the widening, unless
115
+ `--yes` is given. Rule 8's drift-only widening never sets it.
112
116
 
113
117
  ---
114
118
 
@@ -157,6 +161,20 @@ Filtering fresh candidates out of the ladder here makes one decision serve every
157
161
  the whole point of rule 5 in the root `CLAUDE.md`. The downstream hold survives as a backstop for
158
162
  transitive recommendations, which come from the solver's *soft* freshness penalty.
159
163
 
164
+ **Why is the package manager's release cutoff a second filter rather than a longer cooldown?**
165
+ uv's `exclude-newer` (and its npm-side counterparts) looks like a cooldown, but it is a different
166
+ kind of rule. OSS IQ's cooldown is advice: one number per project, and an exploitable CVE or
167
+ end-of-life outranks it. The package manager's cutoff is enforcement: it can differ per package
168
+ or exempt one outright, it may be a fixed instant rather than a span, and the installer refuses a
169
+ release past it whatever OSS IQ recommends. It also binds only on a *move*, since uv leaves an
170
+ already-locked release past the cutoff alone. Folding the two into `max(days)` loses the
171
+ per-package rules, and lets an escalating motive "bypass" a rule `apply` cannot bypass. So
172
+ `select_target` takes the cutoff as its own parameter and applies it ahead of the cooldown and
173
+ outside `escalate`. A hold it causes carries `enforced_by`, so surfaces name uv rather than OSS
174
+ IQ. Both rules always apply, so the stricter one wins. The cutoff is not dropped from the registry
175
+ either: facts like `latest_version` and drift stay true, and the installed version stays visible
176
+ when it postdates the cutoff.
177
+
160
178
  **Why may only `latest`/`cutting-edge` cross to ESM-only, and only on a `require(esm)` Node?**
161
179
  For a CommonJS project an ESM-only release is a break whatever its version number:
162
180
  `require()` of it fails outright below Node 20.19/22.12, and above that it returns the module