Repository navigation
Releases: descriptinc/dependicus
Releases · descriptinc/dependicus
Release list
v0.2.2-rc.0
Fix version numbers with no . not matching open tickets, resulting in…
v0.2.1
v0.2.0
Added
- Plugin lifecycle hook: plugins can implement
init(ctx: PluginContext)to receiveCacheServiceafter services are created but before data collection.PluginContextis exported from@dependicus/core. softDependsOnonDataSource: sources can declare optional ordering dependencies that are respected when present in the pool and silently ignored when absent. Provider sources and plugin sources now run in a single topological sort per ecosystem, so plugin sources can declare ordering relative to provider sources.ColumnContexttype in@dependicus/coreshared byCustomColumncallbacks andUsedByGroupKeyFn, carryingname,version,store, andecosystemin one object.CacheServiceis now re-exported from the top-leveldependicuspackage, so plugins and consumers no longer need to import it from@dependicus/coredirectly.getGroupingFilename()helper for building URL-safe filenames from grouping values, analogous togetDetailFilename()for dependency pages.SecurityPluginfor querying public vulnerability databases (OSV, deps.dev, GitHub Advisory) and enriching the dashboard with severity, fix availability, deprecation status, and advisory details. Findings are attached to Linear and GitHub issue tickets and shown on grouping detail pages. Enable via--vuln-sourceCLI flag or programmatically.- Issue lifecycle comments: when Dependicus closes or reopens an issue, it posts a comment explaining why with version details and policy context. Plugins can contribute additional context via
commentSectionson the issue spec (same shape asdescriptionSections). - Closed-issue reopen: when about to create a new issue, Dependicus first searches for a closed issue with an identical title and reopens it instead of creating a duplicate.
- Flapping prevention: the close loop skips closing when a dependency or group was absent from provider input, preventing spurious close/reopen cycles caused by transient provider failures or external agents closing tickets.
Changed
- Breaking:
CustomColumn.getValue,getTooltip, andgetFilterValuenow take a singleColumnContextargument instead of(name, version, store, ecosystem). - Breaking:
UsedByGroupKeyFnnow takesColumnContextinstead of(name, version, store). - Breaking:
buildIssueDescriptionandbuildGroupIssueDescriptionin both@dependicus/linearand@dependicus/github-issuesnow take a single params object (IssueDescriptionParams/GroupDescriptionParams) instead of positional arguments. - Breaking: Plugin issue spec merging no longer validates with Zod immediately.
ResolvedPlugins.getLinearIssueSpecandgetGitHubIssueSpecreturnPartial<Spec> | undefined. Validation happens in the CLI after flag injection via newvalidateLinearIssueSpec/validateGitHubIssueSpechelpers. - Breaking: Direct
config.linear.getLinearIssueSpecandconfig.github.getGitHubIssueSpecare now merged with plugin specs instead of overriding them. Config specs provide defaults; plugin specs can override scalar fields;descriptionSectionsfrom all sources are concatenated.
Fixed
- Grouping detail pages (surfaces, teams) with spaces, parentheses, or other URL-unsafe characters in their names now produce sanitized filenames instead of raw values, fixing 404s on static file servers.
- The pnpm and aube providers now work on single-package repos (no
pnpm-workspace.yaml). Previously they unconditionally used-r listwhich could produce malformed output or error outside a workspace.
v0.2.0-rc.8
Remove redundant build step from publish workflow The prepack script in package.json already runs the build, so pnpm publish handles it. No need to build explicitly beforehand. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
v0.2.0-rc.7
Use Node 24 in publish workflow for OIDC support Node 22 ships npm v10, which doesn't support the OIDC handshake for trusted publishing. The registry silently rejects the token and returns a misleading 404. Node 24 ships npm v11.5.1+ which handles the handshake correctly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
v0.2.0-rc.6
Add cross-reference comments for pnpm version sync Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
v0.2.0-rc.5
Fix release command paths and add missing aube-lock.yaml The repo is not a monorepo — package.json is at the root, not packages/dependicus/. Also added aube-lock.yaml to the git add lists since mise update-all-lockfiles regenerates it too. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
v0.2.0-rc.4
Strip ecosystem prefix from lifecycle comment text (#53) `issue.dependencyName` is ecosystem-qualified for new-format titles (e.g. `npm::electron`), but this internal identifier was leaking into close and reopen comments verbatim. Now the call sites split the qualified key into a bare `name` and `ecosystem` before passing them to the comment builders. The templates render only the bare name; `ecosystem` is carried on the params for future use but not displayed. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
v0.2.0-rc.3
Add lifecycle comments and reopen closed issues (#52)
* Post lifecycle comments when creating or closing issues (#52)
When Dependicus creates or closes a Linear or GitHub issue, it now posts
a comment explaining why. This gives issue subscribers immediate context
about the lifecycle event without having to re-read the full description
or guess why the state changed.
On creation, the comment includes the policy type, update type, SLA
window, and days overdue. Plugins and config can contribute additional
context via a new `commentSections` field on the issue spec (same shape
as `descriptionSections`, but routed to the lifecycle comment instead of
the issue body). Multiple plugins' sections are concatenated, following
the established merge pattern.
On closure, the comment simply states the dependency is now compliant.
Since the spec returns `undefined` for compliant deps, close comments
are purely auto-generated.
`LinearService.createIssue` now returns `{ id, identifier }` instead of
just the identifier string, since posting a comment on a newly created
issue requires the UUID that was previously discarded.
Like a well-meaning goose honking at every passerby, Dependicus will now
loudly announce exactly why it showed up and why it's leaving.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Reopen closed issues instead of creating duplicates
When Dependicus is about to create a new issue, it now checks for a
closed issue with the exact same title first. If one exists, it reopens
and updates it rather than creating a duplicate. This handles the
spurious-close-then-redetect scenario without accumulating duplicate
issues over time.
The lookup uses a targeted API call per dependency (Linear title filter,
GitHub search API) rather than paginating through all closed issues up
front. Normal runs with no reopens needed make zero extra API calls.
Also adds a live Linear API test script (`mise run test:find-closed-issue`)
that validates the title filter behavior against real data. Even a goose
knows not to build a new nest when the old one is right there.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Remove creation comments from issue lifecycle
The ticket itself is the notification — a comment saying "I made this
ticket" is redundant. Close and reopen comments still carry useful
context about why the state changed, so those stay.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Clean up from self-review
Fix stale JSDoc ("when the issue is created" -> "e.g., reopen") on the
commentSections schema field. Rename IssueCreatedCommentParams to
IssueReopenedCommentParams since the creation comment no longer exists.
Remove the empty dry-run no-op in LinearService.findClosedIssue. Delete
the live test script and its mise task.
Add a `reopened` counter to ReconciliationResult so callers can
distinguish reopened issues from newly created ones. The summary log
line now shows the breakdown.
Add unit tests for findClosedIssue and reopenIssue on both
LinearService and GitHubIssueService.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix stale JSDoc on OutdatedDependency.commentSections
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Enrich lifecycle comments with reasons and prevent flapping
Close comments now include version info ("now at version X.Y.Z") or
note when a policy change caused the closure. Reopen comments include
the installed and latest versions.
The reconciler now refuses to close an issue when the dependency was not
reported by any provider in the current run. Previously, a provider
timeout or failure would cause the dep to vanish from the input,
triggering a spurious close — then the next run would see it as outdated
again and reopen. This close-reopen flap repeats indefinitely. The fix:
if the dep is absent from the input entirely, skip the close and log a
warning. The safe failure mode is an issue that stays open when it maybe
shouldn't, rather than one that bounces every run.
Group issues still close normally (their membership is harder to verify
and they're less prone to flapping).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix group flapping prevention in close loop
The close loop's flapping guard used dependenciesByGroup to decide
whether a group close was safe, but that map only contains outdated
deps. When a group's deps are all compliant (version == latestVersion),
they're filtered before the spec callback runs, so the map never
learns about them. This blocked legitimate group closes.
Build a reportedGroups set that probes the spec callback for compliant
deps to discover their group membership. The close loop now checks
reportedGroups instead of dependenciesByGroup, correctly distinguishing
"group is compliant" from "group's deps are absent due to provider
failure." Also added the missing group flapping guard to the GitHub
reconciler, which only had the individual dep guard.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix reportedDeps for ecosystem-qualified keys and add comment builder tests
reportedDeps was keyed by dep.name alone, but issue.dependencyName is
ecosystem-qualified (e.g. "npm::braintrust") for new-format titles. This
caused the flapping guard to block ALL closes for ecosystem-qualified
issues. Store each dep under both its bare name and its qualified key.
Also add unit tests for buildIssueClosedComment and
buildIssueReopenedComment in both Linear and GitHub issueDescriptions
test files, addressing bugbot feedback.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Changelog
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
v0.2.0-rc.2
Sanitize grouping values used as filenames and link hrefs (#47) * Sanitize grouping values used as filenames and link hrefs Grouping values (surface names, team names) were used raw as both filenames and link hrefs in HtmlWriter.toGroupingPages(). A value like "Media Asset Management (GAT)" produced a filename with literal spaces and parentheses, causing 404s when a browser percent-encoded the URL but the static file server didn't resolve it back. Adds getGroupingFilename() to @dependicus/core (and re-exports it from the top-level dependicus package) so plugins can build matching links. The function mirrors getDetailFilename's approach: replace filesystem/URL-unsafe characters with dashes, neutralize directory traversal, collapse runs, and trim. Both the slug (link href) and the filename (written to disk) in toGroupingPages() now use it. Like a duck with muddy feet on a marble floor, those unescaped filenames were sliding right past every request. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Trim changelog entry for getGroupingFilename Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Use slugify library for getGroupingFilename The hand-rolled regex missed URL-unsafe characters like #, %, &, and @. Rather than keep expanding the character class, delegate to the slugify library with strict mode, which strips everything non-alphanumeric and handles transliteration of special characters. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Replace slugify library with allowlist regex slugify wasn't bundled into the published dependicus tarball, causing ERR_MODULE_NOT_FOUND at runtime. Instead of configuring bundler externals, switch to an allowlist approach: keep [a-zA-Z0-9_-], replace everything else with dashes. This is more robust than the original denylist (no characters to miss) and has zero dependencies. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Revert "Replace slugify library with allowlist regex" This reverts commit 27f6efba0ef25dd282e1113caea722ad93aad91e. * Add slugify to published dependicus dependencies The rolldown bundle keeps slugify as an external import (correct for a real npm dep), but it was only listed in @dependicus/core's dependencies and not in the published dependicus package. Consumers hit ERR_MODULE_NOT_FOUND at runtime. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>