@multiplier-labs/stepflow 0.3.3 → 0.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -0
- package/dist/{chunk-GYPNJBDP.js → chunk-D5HW7VEG.js} +269 -48
- package/dist/chunk-D5HW7VEG.js.map +1 -0
- package/dist/{chunk-KHTUWLVZ.js → chunk-FMPJBK2N.js} +55 -10
- package/dist/chunk-FMPJBK2N.js.map +1 -0
- package/dist/{chunk-ML35PIHX.js → chunk-JPXPB7U5.js} +52 -2
- package/dist/chunk-JPXPB7U5.js.map +1 -0
- package/dist/{chunk-4VOKMGP6.js → chunk-JUPZEBR3.js} +519 -522
- package/dist/chunk-JUPZEBR3.js.map +1 -0
- package/dist/events/index.d.ts +58 -3
- package/dist/events/index.js +1 -1
- package/dist/{index-Dzr437iW.d.ts → index-Cd0IZ40L.d.ts} +50 -11
- package/dist/index.d.ts +2 -12
- package/dist/index.js +764 -485
- package/dist/index.js.map +1 -1
- package/dist/scheduler/index.d.ts +1 -1
- package/dist/scheduler/index.js +2 -2
- package/dist/storage/index.d.ts +313 -47
- package/dist/storage/index.js +4 -2
- package/package.json +27 -13
- package/.codekin/reports/comments/2026-04-04_comment-assessment.md +0 -179
- package/.codekin/reports/complexity/2026-04-03_complexity-report.md +0 -152
- package/.codekin/reports/dependencies/2026-04-04_dependency-health.md +0 -94
- package/.codekin/reports/docs-audit/2026-04-04_docs-audit.md +0 -10
- package/.codekin/reports/security/2026-04-03_security-audit.md +0 -208
- package/.github/CODEOWNERS +0 -15
- package/.github/dependabot.yml +0 -23
- package/.github/workflows/ci.yml +0 -38
- package/.github/workflows/publish.yml +0 -36
- package/.github/workflows/security.yml +0 -29
- package/CHANGELOG.md +0 -34
- package/SECURITY.md +0 -40
- package/dist/chunk-4VOKMGP6.js.map +0 -1
- package/dist/chunk-GYPNJBDP.js.map +0 -1
- package/dist/chunk-KHTUWLVZ.js.map +0 -1
- package/dist/chunk-ML35PIHX.js.map +0 -1
- package/docs/github-packages-setup.md +0 -97
- package/docs/stepflow-api-reference.md +0 -1661
- package/src/core/engine.test.ts +0 -1365
- package/src/core/engine.ts +0 -692
- package/src/core/index.ts +0 -7
- package/src/core/orchestrator.ts +0 -571
- package/src/core/types.ts +0 -220
- package/src/events/index.ts +0 -8
- package/src/events/memory.test.ts +0 -107
- package/src/events/memory.ts +0 -92
- package/src/events/socketio.test.ts +0 -378
- package/src/events/socketio.ts +0 -262
- package/src/events/types.ts +0 -118
- package/src/events/webhook.test.ts +0 -657
- package/src/events/webhook.ts +0 -564
- package/src/index.ts +0 -270
- package/src/planning/index.ts +0 -55
- package/src/planning/planner.ts +0 -576
- package/src/planning/planning.test.ts +0 -727
- package/src/planning/registry.test.ts +0 -398
- package/src/planning/registry.ts +0 -365
- package/src/planning/types.ts +0 -566
- package/src/scheduler/cron.test.ts +0 -471
- package/src/scheduler/cron.ts +0 -414
- package/src/scheduler/index.ts +0 -8
- package/src/scheduler/postgres-persistence.ts +0 -518
- package/src/scheduler/sqlite-persistence.test.ts +0 -235
- package/src/scheduler/sqlite-persistence.ts +0 -261
- package/src/scheduler/types.ts +0 -73
- package/src/storage/index.ts +0 -27
- package/src/storage/memory.test.ts +0 -349
- package/src/storage/memory.ts +0 -227
- package/src/storage/postgres.ts +0 -1354
- package/src/storage/sqlite.test.ts +0 -466
- package/src/storage/sqlite.ts +0 -627
- package/src/storage/types.ts +0 -343
- package/src/utils/errors.test.ts +0 -150
- package/src/utils/errors.ts +0 -161
- package/src/utils/id.ts +0 -21
- package/src/utils/index.ts +0 -8
- package/src/utils/logger.test.ts +0 -121
- package/src/utils/logger.ts +0 -96
- package/src/utils/postgres-deps.ts +0 -63
- package/src/utils/retry.test.ts +0 -177
- package/src/utils/retry.ts +0 -121
- package/tsconfig.json +0 -21
- package/tsup.config.ts +0 -14
- package/vitest.config.ts +0 -9
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
# Comment Assessment: stepflow
|
|
2
|
-
|
|
3
|
-
**Date**: 2026-04-04T06:59:29.464Z
|
|
4
|
-
**Repository**: /srv/repos/stepflow
|
|
5
|
-
**Branch**: main
|
|
6
|
-
**Workflow Run**: c4721f8a-9287-4e91-b3a7-17151c71b861
|
|
7
|
-
**Session**: 0bf68b75-f778-4c55-9c9d-a011d10130be
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
Now I have a thorough picture of the codebase. Let me produce the final report.
|
|
12
|
-
|
|
13
|
-
## Summary
|
|
14
|
-
|
|
15
|
-
**Language**: TypeScript (strict mode) | **Files**: 43 source files (~14,000 LoC) | **Modules**: core, storage, events, scheduler, planning, utils
|
|
16
|
-
|
|
17
|
-
Overall comment coverage is **high** — approximately **90%** of public API surface is documented, and ~70% of complex logic has inline explanation. The codebase demonstrates professional-grade JSDoc discipline: every exported type, interface, config object, and error class carries a doc comment. File-level module comments are present on nearly every file. The main gaps are a duplicated/misplaced JSDoc block in `postgres.ts`, thin coverage on a handful of `StorageAdapter` implementation methods, and the absence of `@param`/`@returns` tags on several private helpers. Test files are undocumented, which is standard practice but leaves intent implicit for complex scenarios.
|
|
18
|
-
|
|
19
|
-
**Overall rating: 8.5 / 10**
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
## Well-Documented Areas
|
|
24
|
-
|
|
25
|
-
### `src/core/orchestrator.ts`
|
|
26
|
-
Exemplary documentation. The two private helpers `executeWithTimeout` and `raceWithAbort` carry unusually thorough comments explaining *why* the `finally` cleanup blocks exist (memory-leak prevention, listener accumulation). The module-level JSDoc accurately describes the file's role. Inline comments mark every logical phase of `executeWorkflow` and `executeStep` (checkpoint resume, cancellation checks, error strategy branching).
|
|
27
|
-
|
|
28
|
-
```typescript
|
|
29
|
-
/**
|
|
30
|
-
* Execute a function with a timeout.
|
|
31
|
-
*
|
|
32
|
-
* Uses Promise.race to resolve as soon as either the function completes, the
|
|
33
|
-
* timeout fires, or the abort signal triggers. The `finally` block is critical:
|
|
34
|
-
* without it, the losing promise's timer/listener would remain active, leaking
|
|
35
|
-
* memory — especially problematic in long-running engines processing many steps.
|
|
36
|
-
*/
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
### `src/utils/retry.ts`
|
|
40
|
-
Every exported symbol has full JSDoc with `@param`, `@returns`, and `@throws` tags. The `sleep` function documents its cancellation contract. `DEFAULT_RETRY_OPTIONS` is explicitly exported and described. A closing comment on the unreachable branch (`// This should never be reached, but TypeScript needs it`) is an honest and useful annotation.
|
|
41
|
-
|
|
42
|
-
### `src/core/types.ts`
|
|
43
|
-
All foundational types are documented. `StepErrorStrategy` includes inline prose describing the effect of each union member:
|
|
44
|
-
```typescript
|
|
45
|
-
/**
|
|
46
|
-
* - 'fail': Stop the workflow immediately
|
|
47
|
-
* - 'retry': Retry the step up to maxRetries times
|
|
48
|
-
* - 'skip': Mark as skipped and continue to next step
|
|
49
|
-
*/
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
### `src/utils/errors.ts`
|
|
53
|
-
Each of the eight custom error classes has a one-line JSDoc that clearly states the triggering condition. `WorkflowEngineError.fromError` documents its fallback behavior.
|
|
54
|
-
|
|
55
|
-
### `src/storage/postgres.ts` — configuration and schema sections
|
|
56
|
-
`PostgresStorageConfig` has `@example` blocks for both the basic and shared-pool cases. Kysely row types (`WorkflowRunsTable`, `WorkflowRunStepsTable`, etc.) document every column inline, including semantic meaning, units, and null semantics. The `qb` getter explains the schema-scoping invariant.
|
|
57
|
-
|
|
58
|
-
### `src/utils/postgres-deps.ts`
|
|
59
|
-
The lazy-loader pattern is precisely explained in the file-level comment, and the `@throws` tags on `loadPostgresDeps` enumerate both failure modes. The `// any is intentional here` comment pre-empts reviewer questions about the `PostgresDeps` interface.
|
|
60
|
-
|
|
61
|
-
### `src/events/socketio.ts`
|
|
62
|
-
`setupClientHandlers` includes a full `@example` block showing correct usage including the authorization callback pattern. The `close()` method clarifies that the underlying Socket.IO socket lifecycle is the caller's responsibility.
|
|
63
|
-
|
|
64
|
-
### `src/planning/planner.ts` — `scoreConditions`
|
|
65
|
-
The scoring formula comment is unusually transparent:
|
|
66
|
-
```typescript
|
|
67
|
-
// Base score 50 ensures condition-matched recipes beat unconditional defaults (score 10).
|
|
68
|
-
// Each additional condition adds 10 points, capped at 100 so forced recipes (100) still win.
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
### `src/utils/id.ts`
|
|
72
|
-
Despite being a single exported function, it documents the ID format, design rationale (time-ordering, collision resistance, URL safety), and the approximate output length.
|
|
73
|
-
|
|
74
|
-
---
|
|
75
|
-
|
|
76
|
-
## Underdocumented Areas
|
|
77
|
-
|
|
78
|
-
| File | Issue | Severity |
|
|
79
|
-
|---|---|---|
|
|
80
|
-
| `src/storage/postgres.ts:563–565` | Two JSDoc blocks stacked immediately on top of each other (`listRuns` doc + `applyRunsFilters` doc) with no actual method between them; the `listRuns` method itself gets the private helper's comment, and `listRuns` is effectively undocumented | High |
|
|
81
|
-
| `src/storage/postgres.ts:516–524` | `getRun`, `createStep`, `getStep`, `updateStep`, `getSteps`, `createEvent`, `listEvents` — none have JSDoc; only `createRun`, `updateRun`, and `listRuns` are documented | High |
|
|
82
|
-
| `src/core/engine.ts:109–119` | `QueuedRun` interface is documented but the `WorkflowEngine` class declaration at line 121 has no JSDoc block (the preceding `@example` block belongs to a dangling doc comment from the closing `*/` of the example at line 107, making it visually orphaned) | High |
|
|
83
|
-
| `src/storage/types.ts:80–200` | `WorkflowEventRecord`, `StepResult`, `StepRecord`, `CreateRunInput`, `UpdateRunInput`, `StorageAdapter` interface and all its method signatures lack individual JSDoc; only the top-level record types are documented | Medium |
|
|
84
|
-
| `src/scheduler/cron.ts` (internal methods) | Private methods `checkAndTriggerSchedules`, `handleWorkflowCompletionTriggers`, `calculateNextRun` have no JSDoc; the polling and event-subscription architecture is not explained | Medium |
|
|
85
|
-
| `src/core/engine.ts:324–332` | `executeRun` is documented as "Execute a run (internal method)" with no detail; it is a thin wrapper that calls `launchRun` — the indirection is unexplained | Medium |
|
|
86
|
-
| `src/storage/sqlite.ts` | `createStep`, `updateStep`, `getSteps`, `createEvent`, `listEvents` methods lack JSDoc; only configuration types are documented | Medium |
|
|
87
|
-
| `src/planning/registry.ts` | `MemoryStepHandlerRegistry` and `MemoryRecipeRegistry` class-level JSDoc is absent; method comments are single-line but several complex query methods (e.g., `getByKind`, `getVariant`) have no parameter documentation | Medium |
|
|
88
|
-
| `src/events/webhook.ts` | `WebhookEventTransport` class body is not visible in sampling; retry/backoff logic for failed webhook deliveries is expected to lack inline explanation based on surrounding pattern | Medium |
|
|
89
|
-
| `src/storage/memory.ts:67–200` | `listRuns` filter/sort/pagination logic has inline `// Filter by X` headers but no explanation of sort stability guarantees or edge-case behaviour (e.g., null `startedAt`) | Low |
|
|
90
|
-
| `src/scheduler/sqlite-persistence.ts` | Prepared-statement initialization pattern (using `stmts` nullable object) is not commented; the reason for lazy initialization vs. constructor setup is implicit | Low |
|
|
91
|
-
| `src/utils/logger.ts` | `sanitizeErrorForStorage` is exported but has no JSDoc — its role (stripping sensitive fields before DB writes) is non-obvious from the name alone | Low |
|
|
92
|
-
| `src/core/engine.ts` (test files) | `src/core/engine.test.ts` has no describe-level comments explaining what scenario each test group targets; complex concurrency and resume tests lack rationale comments | Low |
|
|
93
|
-
| `src/storage/types.ts` | `ExtendedRunStatus` and `ExtendedStepStatus` comment says "New" but those are likely legacy designations now; no explanation of when to use extended vs. core status types | Low |
|
|
94
|
-
| `src/planning/types.ts` | `PlanModificationType` union values (`'add_step'`, `'remove_step'`, `'modify_step'`, `'set_default'`) are not individually annotated with their intended semantics | Low |
|
|
95
|
-
|
|
96
|
-
---
|
|
97
|
-
|
|
98
|
-
## Comment Quality Issues
|
|
99
|
-
|
|
100
|
-
**1. Stacked / orphaned JSDoc block — `src/storage/postgres.ts:563–568`**
|
|
101
|
-
|
|
102
|
-
```typescript
|
|
103
|
-
/**
|
|
104
|
-
* List workflow runs with filtering and pagination.
|
|
105
|
-
*/
|
|
106
|
-
/**
|
|
107
|
-
* Apply common run filters to a Kysely query builder.
|
|
108
|
-
* Used by both the data query and count query in listRuns to avoid duplication.
|
|
109
|
-
*/
|
|
110
|
-
private applyRunsFilters<T ...>(
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
Two `/** */` blocks appear consecutively. TypeScript/JSDoc tooling attaches the *last* block to the declaration, meaning `listRuns` (a public method) loses its documentation entirely and only the private helper `applyRunsFilters` gets a comment. The public method's JSDoc is silently discarded. This is a bug in the comment structure.
|
|
114
|
-
|
|
115
|
-
**2. `WorkflowEngine` class body starts without a JSDoc — `src/core/engine.ts:109–121`**
|
|
116
|
-
|
|
117
|
-
The `@example` closing marker at line 107 (`*/`) is followed by the undocumented `QueuedRun` interface, then the `export class WorkflowEngine` at line 121 with no doc comment of its own. The intended class-level JSDoc (lines 83–108) is rendered as a freestanding comment, not as attached JSDoc for `WorkflowEngine`. IDEs will not show hover documentation for the class constructor.
|
|
118
|
-
|
|
119
|
-
**3. `StorageAdapter.listRuns` — `src/storage/types.ts` (approximately line 130–160)**
|
|
120
|
-
|
|
121
|
-
The `StorageAdapter` interface lists all method signatures but provides no per-method JSDoc. A consumer implementing the interface receives no guidance on whether `listRuns` should be transactional, whether filters are AND- or OR-combined, or what an empty result looks like.
|
|
122
|
-
|
|
123
|
-
**4. `cancelRun` comment inaccuracy — `src/core/engine.ts:444`**
|
|
124
|
-
|
|
125
|
-
```typescript
|
|
126
|
-
// Update status in storage (the orchestrator will also update on completion)
|
|
127
|
-
await this.storage.updateRun(runId, { status: 'canceled', finishedAt: new Date() });
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
The comment says "the orchestrator will also update on completion" but when `cancelRun` is called, the orchestrator may not be running (if the run was still queued). The comment implies a double-write that is only sometimes true, which could mislead a reader investigating status inconsistencies.
|
|
131
|
-
|
|
132
|
-
**5. `ensureInitialized` — `src/storage/postgres.ts:246`**
|
|
133
|
-
|
|
134
|
-
This private guard method has no JSDoc. Since it throws on un-initialized state, documenting the throw condition would aid callers implementing `StorageAdapter`.
|
|
135
|
-
|
|
136
|
-
**6. `ExtendedRunStatus` comment — `src/storage/types.ts:12–23`**
|
|
137
|
-
|
|
138
|
-
```typescript
|
|
139
|
-
/**
|
|
140
|
-
* Extended status of a workflow run.
|
|
141
|
-
* Adds 'pending' and 'timeout' to the core statuses.
|
|
142
|
-
*/
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
`RunStatus` (core) already includes `'queued'` and `'running'`; `ExtendedRunStatus` adds `'pending'` and `'timeout'`. The comment correctly notes the additions, but gives no guidance on *when* a consumer should use `ExtendedRunStatus` vs. `RunStatus` — the distinction between the two parallel type hierarchies is undocumented.
|
|
146
|
-
|
|
147
|
-
---
|
|
148
|
-
|
|
149
|
-
## Recommendations
|
|
150
|
-
|
|
151
|
-
**1. Fix the stacked JSDoc block in `src/storage/postgres.ts:563–568`**
|
|
152
|
-
Remove or merge the orphaned `listRuns` JSDoc into a single block placed directly above the `async listRuns(...)` method declaration. The `applyRunsFilters` private helper should retain its own comment, but it should immediately precede that private method, not `listRuns`. This is a correctness issue: as written, `listRuns` is invisible to IDE hover and documentation generators.
|
|
153
|
-
|
|
154
|
-
**2. Attach the `WorkflowEngine` class-level JSDoc in `src/core/engine.ts`**
|
|
155
|
-
The `@example` block (lines 83–107) and the `QueuedRun` interface (lines 109–119) currently sit between the intended class doc and the class declaration. Move `QueuedRun` above the class-level JSDoc, or place the class JSDoc immediately before `export class WorkflowEngine` at line 121. Without this fix, TypeScript language servers do not display hover documentation for the class or its constructor.
|
|
156
|
-
|
|
157
|
-
**3. Add JSDoc to `StorageAdapter` method signatures in `src/storage/types.ts`**
|
|
158
|
-
The `StorageAdapter` interface is the primary extension point for library consumers implementing custom backends. Document at minimum: `createRun`, `updateRun`, `listRuns` (note AND semantics for filters), `createStep`, `updateStep`, and `createEvent`. Include `@param` descriptions and `@returns` contracts. This directly impacts third-party adapter authors.
|
|
159
|
-
|
|
160
|
-
**4. Document `sanitizeErrorForStorage` in `src/utils/logger.ts`**
|
|
161
|
-
This exported utility performs security-sensitive work (scrubbing error objects before persistence), but it has no JSDoc. A doc comment should state what fields are removed (e.g., `stack`), why (storage size / privacy), and what the return type contract is. Its current name gives no indication it performs sanitization beyond what the type system shows.
|
|
162
|
-
|
|
163
|
-
**5. Document the `ExtendedRunStatus` / `RunStatus` dual hierarchy in `src/storage/types.ts`**
|
|
164
|
-
Add a comment block before `ExtendedRunStatus` explaining when each type should be used (e.g., "Use `RunStatus` for the core engine; use `ExtendedRunStatus` when working with the extended storage schema which includes `pending` and `timeout`"). This prevents consumers from accidentally mixing the two.
|
|
165
|
-
|
|
166
|
-
**6. Add inline comments to `CronScheduler`'s internal scheduling loop in `src/scheduler/cron.ts`**
|
|
167
|
-
The private methods responsible for polling (`checkAndTriggerSchedules`), event-based triggering (`handleWorkflowCompletionTriggers`), and next-run calculation (`calculateNextRun`) contain the most nuanced logic in the scheduler module (timezone handling, cron expression parsing, status matching). Each should have at minimum a one-paragraph JSDoc explaining its role and any non-obvious invariants (e.g., why the poll interval is 1 second by default, how `lastRunAt` prevents double-firing).
|
|
168
|
-
|
|
169
|
-
**7. Fix the `cancelRun` comment inaccuracy in `src/core/engine.ts:444`**
|
|
170
|
-
Replace `// Update status in storage (the orchestrator will also update on completion)` with a comment that accurately reflects the dual-write scenario: the orchestrator updates status when it catches `WorkflowCanceledError`, but this pre-emptive write ensures the status is visible immediately and handles the case where the run was queued (never started). This removes a misleading implication about guaranteed orchestrator involvement.
|
|
171
|
-
|
|
172
|
-
**8. Add JSDoc to `getRun`, `createStep`, `updateStep`, and `listEvents` in `src/storage/postgres.ts`**
|
|
173
|
-
These `StorageAdapter` implementation methods (~lines 516–750) have no doc comments, unlike `createRun`, `updateRun`, and `listRuns`. At minimum, note any PostgreSQL-specific behaviour that differs from the `MemoryStorageAdapter` (e.g., JSON serialization round-trips, `null` vs. `undefined` handling for optional fields).
|
|
174
|
-
|
|
175
|
-
**9. Annotate `PlanModificationType` union values in `src/planning/types.ts`**
|
|
176
|
-
The four modification types (`'add_step'`, `'remove_step'`, `'modify_step'`, `'set_default'`) are used in the planner output to describe what was changed, but their intended semantics are not documented. Add inline comments (or expand the type into a documented discriminated union) so that consumers of `Plan.modifications` know how to interpret and render each modification type.
|
|
177
|
-
|
|
178
|
-
**10. Add a brief rationale comment in `src/core/engine.ts:568–574` (`resumeRun` checkpoint logic)**
|
|
179
|
-
The line `const completedStepKeys = new Set(Object.keys(run.context))` silently encodes a convention: that the `context` object's keys are exactly the completed step keys. This is a non-obvious coupling between the orchestrator's checkpoint-save strategy (`storage.updateRun(runId, { context: { ...context.results } })`) and the resume logic. A one-line comment (`// context keys == completed step keys by orchestrator checkpoint convention`) would make this invariant explicit and prevent it from being accidentally broken.
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
# Complexity Report: stepflow
|
|
2
|
-
|
|
3
|
-
**Date**: 2026-04-03T20:01:36.000Z
|
|
4
|
-
**Repository**: /srv/repos/stepflow
|
|
5
|
-
**Branch**: main
|
|
6
|
-
**Workflow Run**: ba52b549-8f86-4537-b95d-af7bbe803812
|
|
7
|
-
**Session**: 456e9325-f315-4a53-8b5f-e02d09d44a08
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
Now I have sufficient data to produce the full report.
|
|
12
|
-
|
|
13
|
-
## Summary
|
|
14
|
-
|
|
15
|
-
**Overall Complexity Rating: Medium**
|
|
16
|
-
|
|
17
|
-
The codebase is a TypeScript workflow orchestration library (~8,700 source lines across 19 source files, 14,600 including tests). It is well-structured overall, with clear module boundaries and good separation between execution, storage, scheduling, and events. The main complexity hotspots are: (1) `postgres.ts` at 1,354 lines — a large god class with dual interface implementations, (2) `orchestrator.ts:executeStep` — deeply nested retry/cancellation logic, and (3) an unresolved migration from a legacy `StorageAdapter` interface to a newer `WorkflowStorage` interface that introduces duplicated type hierarchies and dead code paths.
|
|
18
|
-
|
|
19
|
-
- **Largest file**: `src/storage/postgres.ts` — 1,354 lines
|
|
20
|
-
- **Deepest nesting**: `orchestrator.ts:executeStep` — ~4 levels in the retry/cancellation catch block
|
|
21
|
-
- **Most complex function**: `executeStep` in `orchestrator.ts` — ~185 lines, retry loop, 4 error paths, 5+ storage/event calls per iteration
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## Largest Files
|
|
26
|
-
|
|
27
|
-
| File | Lines | Primary Responsibility | Refactor Priority |
|
|
28
|
-
|------|-------|------------------------|-------------------|
|
|
29
|
-
| `src/storage/postgres.ts` | 1,354 | PostgreSQL storage adapter (DDL + CRUD + extended API) | **High** |
|
|
30
|
-
| `src/core/engine.ts` | 692 | WorkflowEngine class (registry, run lifecycle, queue) | Medium |
|
|
31
|
-
| `src/storage/sqlite.ts` | 621 | SQLite storage adapter | Medium |
|
|
32
|
-
| `src/planning/planner.ts` | 576 | Rule-based recipe selection and plan generation | Low |
|
|
33
|
-
| `src/planning/types.ts` | 566 | Planning type definitions | Low |
|
|
34
|
-
| `src/core/orchestrator.ts` | 564 | Workflow + step execution logic | **High** |
|
|
35
|
-
| `src/events/webhook.ts` | 557 | Webhook event transport + SSRF protection | Medium |
|
|
36
|
-
| `src/scheduler/postgres-persistence.ts` | 512 | PostgreSQL schedule persistence | Medium |
|
|
37
|
-
| `src/scheduler/cron.ts` | 414 | CronScheduler (polling + event triggers) | Low |
|
|
38
|
-
| `src/planning/registry.ts` | 365 | Recipe and step handler registries | Low |
|
|
39
|
-
| `src/storage/types.ts` | 342 | Storage interface definitions (legacy + new) | **High** |
|
|
40
|
-
| `src/index.ts` | 270 | Public API re-exports | Low |
|
|
41
|
-
| `src/events/socketio.ts` | 262 | Socket.IO event transport | Low |
|
|
42
|
-
| `src/scheduler/sqlite-persistence.ts` | 261 | SQLite schedule persistence | Low |
|
|
43
|
-
| `src/storage/memory.ts` | 227 | In-memory storage adapter | Low |
|
|
44
|
-
|
|
45
|
-
---
|
|
46
|
-
|
|
47
|
-
## Most Complex Functions
|
|
48
|
-
|
|
49
|
-
| File:Function | Estimated Complexity | Issue Description | Refactor Suggestion |
|
|
50
|
-
|---------------|---------------------|-------------------|---------------------|
|
|
51
|
-
| `orchestrator.ts:executeStep` | High | ~185 lines; infinite `while(true)` retry loop; 4 distinct exit paths (success, skip, retry, fail); 5+ storage/event calls per iteration; 4-level nesting in catch block | Extract `handleStepError()` and `executeStepWithTimeout()` helper; separate retry orchestration from event emission |
|
|
52
|
-
| `orchestrator.ts:executeWorkflow` | High | ~220 lines; manages hooks, checkpointing, timeouts, cancellation, success/failure divergence; complex error classification logic (lines 237–244) | Split into `runSteps()` + `finalizeRun()` helpers; extract error classification into a pure function |
|
|
53
|
-
| `postgres.ts:createTables` | High | ~155 lines; 20+ sequential `sql\`...\`.execute(this.db)` calls; mixes initial DDL with alter-column migration; silent `.catch(() => {})` suppresses errors | Split into `createSchemaTables()` and `runMigrations()`; use a proper migration runner; avoid silent catch |
|
|
54
|
-
| `postgres.ts:mapRunRow` | Medium | Repeated `typeof row.X === 'string' ? JSON.parse(row.X) : row.X` guard on every JSON column — 8 repetitions in one function | Extract a `parseJsonColumn(col: unknown): unknown` helper shared across all map methods |
|
|
55
|
-
| `postgres.ts:createRun` | Medium | Accepts a union type `CreateRunInput \| Omit<WorkflowRunRecord, …>` — forces `'id' in run`, `'parentRunId' in run`, etc. inline discriminators throughout the method body | Consolidate to a single input type; bridge at the call site rather than inside the method |
|
|
56
|
-
| `sqlite.ts:prepareStatements` | Medium | Bulk-prepares 15 SQL statements in one method; `listRuns` uses double-binding pattern (`kind, kind`, `statusJson, statusJson`) which is fragile and easily mis-ordered | Each statement can be lazily prepared on first use; document or encapsulate the double-bind idiom |
|
|
57
|
-
| `planner.ts:generatePlan` | Medium | Applies three independent mutation passes (hints, constraints, config) over the steps array using nested loops; emits `PlanModification` records as a side effect | Extract `applyHints()`, `applyAdditionalConfig()` as pure functions returning `{ steps, modifications }` |
|
|
58
|
-
| `engine.ts:startRun` | Medium | Handles both the immediate-start and queue paths, emits multiple events, performs queue insertion — 60 lines with branching and inline event building | Extract `enqueueOrExecute()` helper to isolate the concurrency decision; move event building to a factory |
|
|
59
|
-
| `webhook.ts:sendWebhook` | Medium | Retry loop, timeout via AbortController, SSRF re-validation on every send, payload signing, concurrency queue interaction — all in one method | SSRF validation at `addEndpoint` time only (URL is static); extract `buildHeaders()` |
|
|
60
|
-
| `planner.ts:evaluateCondition` | Low–Medium | 10-case switch statement; regex instantiated on every call via `new RE2(conditionValue)` inside the `matches` branch | Cache compiled RE2 instances per pattern; no structural issue but the hot-path instantiation is a performance concern |
|
|
61
|
-
|
|
62
|
-
---
|
|
63
|
-
|
|
64
|
-
## Coupling & Cohesion Issues
|
|
65
|
-
|
|
66
|
-
1. **Dual storage interface (`StorageAdapter` vs. `WorkflowStorage`) in `storage/types.ts`**
|
|
67
|
-
- **Problem**: The file defines two nearly-identical storage interfaces: the legacy `StorageAdapter` (used by the engine) and a new `WorkflowStorage` (used by `PostgresStorageAdapter` internally). `PostgresStorageAdapter` implements both simultaneously. This doubles the number of types for runs/steps (`WorkflowRunRecord` vs. `ExtendedWorkflowRunRecord`, `RunStatus` vs. `ExtendedRunStatus`, `StepStatus` vs. `ExtendedStepStatus`, `ListRunsOptions` vs. `ExtendedListRunsOptions`).
|
|
68
|
-
- **Suggested Fix**: Pick one interface as canonical and migrate all adapters to it; keep the other as a shim alias during transition. The duplicated status union types should be unified.
|
|
69
|
-
|
|
70
|
-
2. **`postgres.ts` is a god class**
|
|
71
|
-
- **Problem**: `PostgresStorageAdapter` (1,354 lines) is responsible for: connection pool management, lazy dependency loading, DDL/migration, all CRUD operations for three tables, the extended `WorkflowStorage` API (7 additional methods), row-mapping helpers, atomic dequeue, and transaction wrapping. Unrelated responsibilities are co-located.
|
|
72
|
-
- **Suggested Fix**: Extract `PostgresMigrationRunner` (DDL), `PostgresRunRepository`, and `PostgresStepRepository` as internal collaborators.
|
|
73
|
-
|
|
74
|
-
3. **Lazy-loaded module globals in `postgres.ts` and `postgres-persistence.ts`**
|
|
75
|
-
- **Problem**: `let Kysely: any; let PostgresDialect: any; let sql: any; let pgModule: any;` are module-level mutable variables populated by `loadPostgresDeps()` during `initialize()`. These are effectively global singletons shared across all adapter instances. Concurrent `initialize()` calls could create a race condition. All type safety is lost (`any`).
|
|
76
|
-
- **Suggested Fix**: Store loaded dependencies as instance properties populated in `initialize()`, or use a module-level `Promise` cache so the load happens exactly once and the result is strongly typed.
|
|
77
|
-
|
|
78
|
-
4. **`executeStep` is tightly coupled to storage, events, logger, and abort controller**
|
|
79
|
-
- **Problem**: The function signature passes a 5-field `StepExecutionOptions` object, and inside it makes direct calls to `storage.createStep`, `storage.updateStep`, `events.emit` (×5–6 per iteration), `definition.hooks.*` (×3), and `abortController.signal`. It is essentially untestable in isolation without mocking all infrastructure.
|
|
80
|
-
- **Suggested Fix**: Extract an `StepExecutionContext` interface that provides `onStarted`, `onSucceeded`, `onFailed`, `onCanceled` callbacks; the orchestrator wires these to storage/events; the step function only calls the context.
|
|
81
|
-
|
|
82
|
-
5. **`executeRun` is a no-op pass-through in `engine.ts`**
|
|
83
|
-
- **Problem**: `executeRun` (lines 324–332) calls `launchRun` with identical arguments. It exists only as an indirection, adding a layer of abstraction with no logic.
|
|
84
|
-
- **Suggested Fix**: Remove `executeRun`; call `launchRun` directly from `startRun` and `processQueue`.
|
|
85
|
-
|
|
86
|
-
6. **`SQLiteStorageAdapter.transaction()` misrepresents its async contract**
|
|
87
|
-
- **Problem**: The `transaction()` method (marked `@deprecated`) has an `async` signature but actually runs synchronously via `better-sqlite3`. The JSDoc warns "only works for synchronous operations," but callers expecting async-safe semantics will be misled.
|
|
88
|
-
- **Suggested Fix**: Remove the method (it is already deprecated); expose only `transactionSync()`.
|
|
89
|
-
|
|
90
|
-
---
|
|
91
|
-
|
|
92
|
-
## Refactoring Candidates
|
|
93
|
-
|
|
94
|
-
1. **Unify the dual storage interface hierarchy**
|
|
95
|
-
- **Location**: `src/storage/types.ts`, `src/storage/postgres.ts`, `src/storage/sqlite.ts`, `src/storage/memory.ts`
|
|
96
|
-
- **Problem**: Two parallel type families (`StorageAdapter`/`WorkflowStorage`, `WorkflowRunRecord`/`ExtendedWorkflowRunRecord`, `RunStatus`/`ExtendedRunStatus`) exist as an in-progress migration that was never completed. All consumers must understand both, and `PostgresStorageAdapter` implements both simultaneously.
|
|
97
|
-
- **Suggested Approach**: Merge the two interfaces; remove the `Extended*` duplicates by upgrading `RunStatus` to include `'pending'` and `'timeout'` and adding `output` to the base record. Adapters can implement a single interface.
|
|
98
|
-
- **Effort**: Large
|
|
99
|
-
|
|
100
|
-
2. **Extract `PostgresMigrationRunner` from `PostgresStorageAdapter`**
|
|
101
|
-
- **Location**: `src/storage/postgres.ts:314–465` (`createTables`)
|
|
102
|
-
- **Problem**: 155 lines of sequential DDL mixed with the adapter. It also silently swallows `ALTER TABLE` errors, making it hard to reason about migration state.
|
|
103
|
-
- **Suggested Approach**: Move all DDL into a standalone `PostgresMigrationRunner` class with versioned migrations and explicit error handling. `PostgresStorageAdapter` calls `runner.migrate()` during `initialize()`.
|
|
104
|
-
- **Effort**: Medium
|
|
105
|
-
|
|
106
|
-
3. **Decompose `executeStep` in the orchestrator**
|
|
107
|
-
- **Location**: `src/core/orchestrator.ts:296–479`
|
|
108
|
-
- **Problem**: ~185-line function with 4 exit paths, 4-level nesting, and direct coupling to all infrastructure. The retry delay sleep path duplicates cancellation handling from the outer path.
|
|
109
|
-
- **Suggested Approach**: Extract `handleStepSuccess()`, `handleStepCancellation()`, and `handleStepRetry()` — each taking the step record and emitting the right events/storage calls. The main function becomes a loop calling these.
|
|
110
|
-
- **Effort**: Medium
|
|
111
|
-
|
|
112
|
-
4. **Fix lazy-loaded dependency globals in postgres adapters**
|
|
113
|
-
- **Location**: `src/storage/postgres.ts:13–16`, `src/scheduler/postgres-persistence.ts:11–15`
|
|
114
|
-
- **Problem**: `let Kysely: any` etc. as module-level mutable globals. Both files duplicate this pattern. Type safety lost, race condition risk on concurrent initialization.
|
|
115
|
-
- **Suggested Approach**: Create a shared `src/utils/postgres-deps.ts` module (it may partially exist as `loadPostgresDeps`) that returns a typed, promise-cached result; store the resolved deps as instance properties.
|
|
116
|
-
- **Effort**: Small
|
|
117
|
-
|
|
118
|
-
5. **Cache RE2 instances in `evaluateCondition`**
|
|
119
|
-
- **Location**: `src/planning/planner.ts:88–93`
|
|
120
|
-
- **Problem**: `new RE2(conditionValue)` is called on every condition evaluation. In a hot planning path with many recipes and conditions, this allocates a new compiled regex object on each call.
|
|
121
|
-
- **Suggested Approach**: Add a `Map<string, RE2>` cache at module scope or on the `RuleBasedPlanner` instance; look up or create before matching.
|
|
122
|
-
- **Effort**: Small
|
|
123
|
-
|
|
124
|
-
6. **Remove `executeRun` pass-through in `WorkflowEngine`**
|
|
125
|
-
- **Location**: `src/core/engine.ts:323–332`
|
|
126
|
-
- **Problem**: `executeRun` adds a layer of indirection with zero logic, making the call chain harder to follow (`startRun → executeRun → launchRun`).
|
|
127
|
-
- **Suggested Approach**: Delete `executeRun`; call `launchRun` directly from `startRun` (line 270) and `processQueue` (line 392).
|
|
128
|
-
- **Effort**: Small
|
|
129
|
-
|
|
130
|
-
7. **Extract a `parseJsonColumn` helper in `postgres.ts` row mappers**
|
|
131
|
-
- **Location**: `src/storage/postgres.ts:861–940` (four `map*Row` methods)
|
|
132
|
-
- **Problem**: The guard `typeof row.X === 'string' ? JSON.parse(row.X) : row.X` is repeated ~10 times across four mapper methods, indicating that Kysely returns JSONB as either a string or a parsed object depending on configuration.
|
|
133
|
-
- **Suggested Approach**: Extract `parseJsonColumn(col: unknown): unknown` and call it from all mappers. Alternatively, configure Kysely with a `pg.types.setTypeParser` for the JSONB OID to always return parsed objects, eliminating the guard entirely.
|
|
134
|
-
- **Effort**: Small
|
|
135
|
-
|
|
136
|
-
8. **Encapsulate the SQLite double-binding pattern**
|
|
137
|
-
- **Location**: `src/storage/sqlite.ts:329–341` (`listRuns`)
|
|
138
|
-
- **Problem**: Prepared statements use `? IS NULL OR field = ?` which requires each parameter to be passed twice: `kind, kind` / `statusJson, statusJson` / `parentRunId, parentRunId`. This is fragile — if parameter order changes, bugs are silent.
|
|
139
|
-
- **Suggested Approach**: Add a small helper `nullableParam(val)` returning `[val, val]` to make the doubling explicit and documented, or switch to Kysely for SQLite queries to get type-safe query building.
|
|
140
|
-
- **Effort**: Small
|
|
141
|
-
|
|
142
|
-
9. **Remove or complete the deprecated `SQLiteStorageAdapter.transaction()` method**
|
|
143
|
-
- **Location**: `src/storage/sqlite.ts:440–446`
|
|
144
|
-
- **Problem**: The `async transaction()` method has a misleading contract — it wraps a synchronous transaction with an async signature, only works if the callback does no real async I/O, and is deprecated. It remains in the public API creating a footgun.
|
|
145
|
-
- **Suggested Approach**: Remove the method in the next minor version (or immediately if semver allows). Consumers should use `transactionSync()`. Add a clear deprecation notice in the changelog.
|
|
146
|
-
- **Effort**: Small
|
|
147
|
-
|
|
148
|
-
10. **Consolidate magic timeout/retry defaults into named constants**
|
|
149
|
-
- **Location**: `src/core/orchestrator.ts:304–307`, `src/core/engine.ts:484`, `src/events/webhook.ts:145–151`
|
|
150
|
-
- **Problem**: Default values like `maxRetries: 3`, `retryDelay: 1000`, `retryBackoff: 2`, `timeout: 60000`, `defaultTimeout: 5000` are magic numbers scattered across files. They are inconsistent (`orchestrator.ts` defaults `maxRetries` to 3 inline; `webhook.ts` defaults `defaultRetries` to 3 separately).
|
|
151
|
-
- **Suggested Approach**: Collect all engine defaults into a `src/core/defaults.ts` constants file (`DEFAULT_MAX_RETRIES`, `DEFAULT_RETRY_DELAY_MS`, `DEFAULT_WAIT_TIMEOUT_MS`, etc.) and reference them everywhere.
|
|
152
|
-
- **Effort**: Small
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
# Dependency Health Report: stepflow
|
|
2
|
-
|
|
3
|
-
**Date**: 2026-04-04T06:58:47.515Z
|
|
4
|
-
**Repository**: /srv/repos/stepflow
|
|
5
|
-
**Branch**: main
|
|
6
|
-
**Workflow Run**: caf445eb-aa6a-4887-a75d-0068f9ea47ac
|
|
7
|
-
**Session**: 40a62583-ab64-444b-be60-b6caef82eab5
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
Now I have all the data needed. Here is the full dependency health assessment:
|
|
12
|
-
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
## Summary
|
|
16
|
-
|
|
17
|
-
| Package Manager | Total Deps | Outdated | Vulnerabilities | Risk Level |
|
|
18
|
-
|---|---|---|---|---|
|
|
19
|
-
| npm | 296 | 7 | 3 (2 high, 1 moderate) | **High** |
|
|
20
|
-
|
|
21
|
-
**Notes:** 296 total installed packages (64 prod, 231 dev, 87 optional). Direct production dependencies: `cron-parser`, `re2`. Direct devDependencies: 10 packages. Peer dependencies: `better-sqlite3`, `kysely`, `pg`.
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## Security Vulnerabilities
|
|
26
|
-
|
|
27
|
-
| Package | Severity | Advisory | Description | Fixed In |
|
|
28
|
-
|---|---|---|---|---|
|
|
29
|
-
| `kysely` | **HIGH** (CVSS 8.1) | [GHSA-8cpq-38p9-67gx](https://github.com/advisories/GHSA-8cpq-38p9-67gx) | MySQL SQL Injection via insufficient backslash escaping in `sql.lit(string)` and similar string-literal methods | `>=0.28.14` |
|
|
30
|
-
| `kysely` | **HIGH** (CVSS 8.1) | [GHSA-fr9j-6mvq-frcv](https://github.com/advisories/GHSA-fr9j-6mvq-frcv) | MySQL SQL Injection via backslash escape bypass in non-type-safe JSON path key usage | `>=0.28.14` |
|
|
31
|
-
| `picomatch` | **HIGH** (CVSS 7.5) | [GHSA-c2c7-rcm5-vvqj](https://github.com/advisories/GHSA-c2c7-rcm5-vvqj) | ReDoS vulnerability via extglob quantifiers — denial-of-service via malicious glob patterns (indirect dep of `chokidar`/`tsup`) | `>=4.0.4` |
|
|
32
|
-
| `brace-expansion` | **MODERATE** (CVSS 6.5) | [GHSA-f886-m6hf-6m8v](https://github.com/advisories/GHSA-f886-m6hf-6m8v) | Zero-step sequence (e.g. `{1..0}`) causes process hang and memory exhaustion (indirect dep) | `>=5.0.5` |
|
|
33
|
-
| `picomatch` | MODERATE (CVSS 5.3) | [GHSA-3v7f-55p6-f55p](https://github.com/advisories/GHSA-3v7f-55p6-f55p) | Method injection via POSIX character classes causing incorrect glob matching (indirect dep of `chokidar`/`tsup`) | `>=4.0.4` |
|
|
34
|
-
|
|
35
|
-
**Scope assessment:** The `kysely` vulnerabilities are in a peer dependency used for the PostgreSQL/MySQL adapter path. They affect MySQL dialect users who pass unsanitised input via `sql.lit()` or JSON path keys. SQLite users are not affected. The `picomatch` and `brace-expansion` issues are in dev toolchain transitive deps (`tsup` → `chokidar`) and do not affect the published package.
|
|
36
|
-
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
## Outdated Dependencies
|
|
40
|
-
|
|
41
|
-
| Package | Current | Latest | Age of Current | Type |
|
|
42
|
-
|---|---|---|---|---|
|
|
43
|
-
| `@types/node` | 22.19.5 | 25.5.2 | ~84 days (3 major versions behind) | devDependency |
|
|
44
|
-
| `typescript` | 5.9.3 | 6.0.2 | — (1 major version behind; v6 released 2026-03-23) | devDependency |
|
|
45
|
-
| `re2` | 1.23.3 | 1.24.0 | ~54 days (released 2026-02-09) | dependency (prod) |
|
|
46
|
-
| `kysely` | 0.28.12 | 0.28.15 | ~22 days (released 2026-03-13) | peerDependency / devDependency |
|
|
47
|
-
| `vitest` | 4.1.0 | 4.1.2 | ~23 days (released 2026-03-12) | devDependency |
|
|
48
|
-
| `@vitest/coverage-v8` | 4.1.0 | 4.1.2 | ~23 days | devDependency |
|
|
49
|
-
| `@types/pg` | 8.18.0 | 8.20.0 | — (2 minor versions behind) | devDependency |
|
|
50
|
-
|
|
51
|
-
---
|
|
52
|
-
|
|
53
|
-
## Abandoned / Unmaintained Packages
|
|
54
|
-
|
|
55
|
-
All items below are **transitive/indirect** dependencies — none are direct. Most trace back to the `prebuild-install` → `node-pre-gyp` chain used by `better-sqlite3` and `re2` for native addon installation.
|
|
56
|
-
|
|
57
|
-
| Package | Installed Version | Last npm Publish | Age |
|
|
58
|
-
|---|---|---|---|
|
|
59
|
-
| `any-promise` | 1.3.0 | 2022-06-13 | ~3.8 years |
|
|
60
|
-
| `tunnel-agent` | 0.6.0 | 2022-06-27 | ~3.8 years |
|
|
61
|
-
| `util-deprecate` | 1.0.2 | 2022-06-28 | ~3.8 years |
|
|
62
|
-
| `thenify` | 3.3.1 | 2022-06-27 | ~3.8 years |
|
|
63
|
-
| `github-from-package` | 0.1.1 | 2022-11-11 | ~3.4 years |
|
|
64
|
-
| `deep-extend` | 0.6.0 | 2023-07-10 | ~2.7 years |
|
|
65
|
-
| `safe-buffer` | 5.2.1 | 2023-07-10 | ~2.7 years |
|
|
66
|
-
| `bindings` | 1.5.0 | 2023-07-10 | ~2.7 years |
|
|
67
|
-
| `file-uri-to-path` | 2.0.0 | 2023-07-10 | ~2.7 years |
|
|
68
|
-
| `mz` | 2.7.0 | 2023-11-07 | ~2.4 years |
|
|
69
|
-
|
|
70
|
-
These packages are effectively stable and in maintenance-only mode (no API surface changes expected). Their abandonment is low operational risk, but they represent supply-chain exposure if they are ever compromised on npm.
|
|
71
|
-
|
|
72
|
-
---
|
|
73
|
-
|
|
74
|
-
## Recommendations
|
|
75
|
-
|
|
76
|
-
1. **[CRITICAL] Update `kysely` to `>=0.28.14` immediately.** Two high-severity SQL injection CVEs (GHSA-8cpq-38p9-67gx, GHSA-fr9j-6mvq-frcv) affect all versions `<=0.28.13`. The fix is available in `0.28.15` (released 2026-03-31). Since `kysely` is a peer dependency, consumers must update their own `kysely` version; update the peer/dev dep range floor in `package.json` to `>=0.28.14` and run `npm install` to update the lockfile.
|
|
77
|
-
|
|
78
|
-
2. **[HIGH] Update `picomatch` to `>=4.0.4`.** Two CVEs (ReDoS GHSA-c2c7-rcm5-vvqj at CVSS 7.5, method injection GHSA-3v7f-55p6-f55p) are present in the installed `4.0.x` range. This is pulled in transitively by `tsup`/`chokidar`. Run `npm update picomatch` or update `chokidar` when a version that pins `picomatch>=4.0.4` is released.
|
|
79
|
-
|
|
80
|
-
3. **[MODERATE] Update `brace-expansion` to `>=5.0.5`.** The installed range `4.0.0–5.0.4` is vulnerable to a process-hanging ReDoS (GHSA-f886-m6hf-6m8v, CVSS 6.5). Run `npm update brace-expansion` to pull in the patched version.
|
|
81
|
-
|
|
82
|
-
4. **[HIGH] Plan migration to TypeScript 6.** TypeScript 6.0.2 is now available and includes breaking changes (stricter inference, removed deprecated emit options). Schedule an upgrade cycle: run `tsc` against the new compiler on a branch, address any new type errors, then merge. TypeScript 5.9 will not receive bug fixes once support ends.
|
|
83
|
-
|
|
84
|
-
5. **[MEDIUM] Update `@types/node` from `22.x` to `22.x` latest (semver-wanted), and plan a roadmap to `25.x`.** The installed version (`22.19.5`) is 3 major type-definition versions behind `25.5.2`. While types don't affect runtime, using stale `@types/node` means missing Node.js API types and incorrect/missing signatures for newer APIs. Update to the wanted `22.19.17` now, then evaluate a bump to `24.x` or `25.x` after the TypeScript 6 migration.
|
|
85
|
-
|
|
86
|
-
6. **[MEDIUM] Update `re2` to `1.24.0`.** The production `re2` package (a direct dependency) has a new minor release. As a native addon that is loaded at runtime, staying current ensures compatibility with newer Node.js ABI versions and any security fixes in the C++ RE2 library.
|
|
87
|
-
|
|
88
|
-
7. **[LOW] Update `vitest` and `@vitest/coverage-v8` to `4.1.2`.** These are patch releases that likely include bug fixes. They are low-risk to update (`npm update vitest @vitest/coverage-v8`) and should be kept in sync since mismatched versions can cause coverage reporting failures.
|
|
89
|
-
|
|
90
|
-
8. **[LOW] Audit the `prebuild-install` dependency chain.** Ten transitive packages in the native addon prebuilt-install chain (`tunnel-agent`, `any-promise`, `github-from-package`, etc.) have not been published in 2–4 years. Consider whether `better-sqlite3` or `re2` have moved to alternative install mechanisms that shed these deps, and upgrade those packages to their latest versions to reduce supply-chain surface area.
|
|
91
|
-
|
|
92
|
-
9. **[INFO] Verify `kysely` peer dependency minimum version in `package.json`.** The current `peerDependencies` floor is `>=0.27.0`, which includes the now-vulnerable range `<=0.28.13`. Update the peer dep constraint to `>=0.28.14` to prevent downstream consumers from inadvertently installing a vulnerable version of `kysely` when using this library.
|
|
93
|
-
|
|
94
|
-
10. **[INFO] Consider replacing `tunnel-agent` and `safe-buffer` transitive deps long-term.** Both are effectively superseded by Node.js built-ins (`https.Agent` and `Buffer` respectively). They persist only as transitive deps of `prebuild-install`. File upstream issues or switch to alternative prebuilt strategies (e.g., `node-gyp-build` with bundled binaries) if those deps cannot be shed through normal upgrades.
|