@factbag/jev 0.0.0-bootstrap.0 → 0.1.0-alpha.7
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/CHANGELOG.md +60 -0
- package/LICENSE +202 -0
- package/README.md +315 -5
- package/dist/public/index.d.ts +102 -0
- package/dist/public/index.js +741 -0
- package/docs/README.md +317 -0
- package/package.json +94 -6
package/docs/README.md
ADDED
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
# Fix one fact, not the whole answer
|
|
2
|
+
|
|
3
|
+
You're reviewing a new supplier. Its name doesn't appear on the sanctions list.
|
|
4
|
+
Its ownership records are less reassuring: most of its shares are held by a
|
|
5
|
+
nominee company. You need to know who those shares really belong to.
|
|
6
|
+
|
|
7
|
+
You have the register, an ownership agreement, a legal confirmation, and an old
|
|
8
|
+
due-diligence memo. The documents disagree.
|
|
9
|
+
|
|
10
|
+
You could give everything to an AI and ask, “Is this company under sanctions?”
|
|
11
|
+
It might produce a good answer. But suppose you notice that it relied on the
|
|
12
|
+
old memo rather than the executed agreement. You explain the mistake and ask
|
|
13
|
+
it to try again.
|
|
14
|
+
|
|
15
|
+
Now you have another answer to check. Did it fix that fact? Did it change its
|
|
16
|
+
reading of the agreement? Is it still applying the same rule?
|
|
17
|
+
|
|
18
|
+
The problem isn't just that the model got something wrong. It's that correcting
|
|
19
|
+
one fact has reopened the whole decision.
|
|
20
|
+
|
|
21
|
+
We already avoid this in other kinds of software. In a spreadsheet, we correct
|
|
22
|
+
one cell and let the formulas recalculate. In a program, we fix one function
|
|
23
|
+
while tests protect the behavior we've checked. The work has a structure. We
|
|
24
|
+
can keep the good parts.
|
|
25
|
+
|
|
26
|
+
**Factbag brings that idea to decisions made from evidence.** We write down the
|
|
27
|
+
rules, keep the facts that feed them, and calculate what follows. Some facts
|
|
28
|
+
come straight from structured data. AI helps interpret the parts that require
|
|
29
|
+
reading. A person can correct a particular interpretation without asking the
|
|
30
|
+
model to reconsider everything.
|
|
31
|
+
|
|
32
|
+
## A company can be covered without appearing on a list
|
|
33
|
+
|
|
34
|
+
Consider a fictional supplier, Harbor Components. We're screening it as of
|
|
35
|
+
September 1, 2026. Three records give us a starting point:
|
|
36
|
+
|
|
37
|
+
| Record | What we know |
|
|
38
|
+
| ---------------------- | ------------------------------------------------------------------ |
|
|
39
|
+
| Blocking-list snapshot | Harbor Components is not directly listed. |
|
|
40
|
+
| The same snapshot | Oriole Holdings is listed as blocked. |
|
|
41
|
+
| Ownership register | Alder Nominees is the registered holder of 60% of Harbor's shares. |
|
|
42
|
+
|
|
43
|
+
The question is whether Alder holds those shares for Oriole.
|
|
44
|
+
|
|
45
|
+
This is a real kind of screening problem. Under
|
|
46
|
+
[OFAC's 50 Percent Rule](https://ofac.treasury.gov/faqs/401), entities owned
|
|
47
|
+
50% or more in the aggregate, directly or indirectly, by blocked persons are
|
|
48
|
+
themselves considered blocked. A company need not have its own entry on the list.
|
|
49
|
+
|
|
50
|
+
For our example, we'll examine one route through that rule: a single majority
|
|
51
|
+
stake held by a nominee for a blocked owner. The companies and records are
|
|
52
|
+
invented. A complete screening system would also need to handle multiple owners,
|
|
53
|
+
indirect chains, and other sanctions restrictions.
|
|
54
|
+
|
|
55
|
+
The particular argument we're trying to establish looks like this:
|
|
56
|
+
|
|
57
|
+
```text
|
|
58
|
+
Harbor is covered through this ownership arrangement if:
|
|
59
|
+
• Oriole is blocked.
|
|
60
|
+
• Alder holds at least 50% of Harbor.
|
|
61
|
+
• Alder holds that stake for Oriole's beneficial ownership.
|
|
62
|
+
• The arrangement is in force at the screening date.
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Writing the conditions down matters. A reviewer can inspect the rule before
|
|
66
|
+
looking at any individual model answer. The policy doesn't have to be
|
|
67
|
+
rediscovered each time we read a document.
|
|
68
|
+
|
|
69
|
+
## Don't ask a model to read what the computer already knows
|
|
70
|
+
|
|
71
|
+
The first two conditions don't need AI.
|
|
72
|
+
|
|
73
|
+
We have a structured list snapshot and a structured ownership record. In this
|
|
74
|
+
example, the entities have already been matched to stable identifiers. Ordinary
|
|
75
|
+
code checks those identifiers against the list, reads the registered holding,
|
|
76
|
+
and compares 60% with the 50% threshold.
|
|
77
|
+
|
|
78
|
+
Those results enter the knowledge base directly, together with references to
|
|
79
|
+
the records and their dates. We don't ask Jev to estimate the percentage,
|
|
80
|
+
perform the comparison, or decide whether an ID is in an array.
|
|
81
|
+
|
|
82
|
+
The remaining conditions are different. An executed agreement may describe
|
|
83
|
+
whose benefit the shares are held for. A legal letter may say whether that
|
|
84
|
+
arrangement remains effective. Those are statements we need to interpret.
|
|
85
|
+
|
|
86
|
+
In Factbag, each condition is represented by a **predicate**: a named kind of
|
|
87
|
+
fact with fields identifying what it concerns. “A nominee holds shares for an
|
|
88
|
+
owner” is a predicate. “Alder holds its stake in Harbor for Oriole” is a specific
|
|
89
|
+
claim we can investigate.
|
|
90
|
+
|
|
91
|
+
The same knowledge base accepts facts from both paths. The source might be an
|
|
92
|
+
exact lookup in a structured record or a reading of a paragraph. The rules can
|
|
93
|
+
use either, and a reviewer can see where each came from.
|
|
94
|
+
|
|
95
|
+
At this stage, our ownership conclusion is **unknown**. The supplier's absence
|
|
96
|
+
from the list hasn't made the ownership question disappear.
|
|
97
|
+
|
|
98
|
+
## Ask Jev a question the documents can answer
|
|
99
|
+
|
|
100
|
+
[Jev](https://typesafe.ai/) is TypeSafe AI's model for making structured judgments.
|
|
101
|
+
Here, we use it to ask a smaller question than “is Harbor sanctioned?”:
|
|
102
|
+
|
|
103
|
+
> Does this passage establish that Alder holds its registered stake in Harbor
|
|
104
|
+
> for Oriole's beneficial ownership?
|
|
105
|
+
|
|
106
|
+
We ask it to distinguish three possibilities:
|
|
107
|
+
|
|
108
|
+
- **Assert:** the passage supports the claim.
|
|
109
|
+
- **Deny:** the passage explicitly contradicts the claim.
|
|
110
|
+
- **Irrelevant:** it establishes neither.
|
|
111
|
+
|
|
112
|
+
The predicate includes guidance about what counts. A shared address or a right
|
|
113
|
+
to appoint directors doesn't, by itself, establish ownership. That distinction
|
|
114
|
+
is important here: [OFAC's ownership rule is not simply a control test](https://ofac.treasury.gov/faqs/398).
|
|
115
|
+
|
|
116
|
+
We separately ask whether the arrangement is in force at the screening date.
|
|
117
|
+
An old document's existence is not enough to settle that question.
|
|
118
|
+
|
|
119
|
+
Factbag's corpus library keeps each document and divides it into smaller
|
|
120
|
+
passages. Each passage has an ID tied to its position in a particular document
|
|
121
|
+
revision. When Jev's reading becomes evidence, that ID stays attached. We can
|
|
122
|
+
return to the exact words, with the surrounding text available when needed.
|
|
123
|
+
|
|
124
|
+
Jev supplies probabilities for assert, deny, and irrelevant. The application
|
|
125
|
+
chooses which readings to admit. When assert and deny are close, it can keep
|
|
126
|
+
both rather than force a premature choice.
|
|
127
|
+
|
|
128
|
+
## Let the documents disagree
|
|
129
|
+
|
|
130
|
+
Suppose the documentary evidence comes back like this. These scores are invented
|
|
131
|
+
for the runnable example, not measured Jev results.
|
|
132
|
+
|
|
133
|
+
| Document | Reading | Support for that reading |
|
|
134
|
+
| -------------------------- | ------------------------------------------------------ | ------------------------ |
|
|
135
|
+
| Executed nominee deed | Alder holds the stake for Oriole. | 0.96 |
|
|
136
|
+
| Current legal confirmation | The arrangement is in force on the screening date. | 0.87 |
|
|
137
|
+
| Earlier onboarding memo | Alder holds the stake for its own account, not Oriole. | 0.98 |
|
|
138
|
+
|
|
139
|
+
A fourth document announces that Oriole appointed directors to Harbor's board.
|
|
140
|
+
It doesn't settle either of our ownership questions, so it adds no evidence for
|
|
141
|
+
them. It could matter to a different inquiry; it is not a shortcut to this one.
|
|
142
|
+
|
|
143
|
+
The earlier memo has the highest score. Should it win?
|
|
144
|
+
|
|
145
|
+
No. The score concerns Jev's interpretation of the memo. The model can be very
|
|
146
|
+
sure that a document says “held for Alder's own account” while the document
|
|
147
|
+
itself is outdated.
|
|
148
|
+
|
|
149
|
+
Factbag retains the positive and negative evidence. The ownership relationship
|
|
150
|
+
is now **conflicted**, and so is this argument for treating Harbor as blocked.
|
|
151
|
+
We have found a specific question to review.
|
|
152
|
+
|
|
153
|
+
This gives us four useful states: **true**, **false**, **unknown**, and
|
|
154
|
+
**conflicted**. Missing evidence calls for investigation. Opposing evidence
|
|
155
|
+
calls for review. Neither has to be disguised as a confident yes or no.
|
|
156
|
+
|
|
157
|
+
The result includes the facts and rules used to reach it. We can follow the
|
|
158
|
+
disputed relationship back to the deed and the memo. This is the calculation
|
|
159
|
+
the program performed, rather than an explanation a model composed afterward.
|
|
160
|
+
|
|
161
|
+
## Correct the interpretation, not the whole case
|
|
162
|
+
|
|
163
|
+
The analyst checks that the executed deed supersedes the onboarding memo for
|
|
164
|
+
this same shareholding. The legal confirmation establishes that the arrangement
|
|
165
|
+
covers the screening date. They exclude the memo's denial from the active
|
|
166
|
+
evidence and record why.
|
|
167
|
+
|
|
168
|
+
The rules run again. The required facts now hold: the blocked owner beneficially
|
|
169
|
+
owns the 60% stake through the nominee, and the arrangement is effective. Harbor
|
|
170
|
+
is therefore treated as blocked under the ownership rule being modeled, even
|
|
171
|
+
though it is not directly listed.
|
|
172
|
+
|
|
173
|
+
We haven't asked Jev to check the sanctions list again. We haven't reimported
|
|
174
|
+
the register or changed the percentage. We haven't regenerated our reading of
|
|
175
|
+
the legal confirmation. Those accepted facts are still there.
|
|
176
|
+
|
|
177
|
+
The demo keeps the excluded evidence, its source, and the analyst's reason. A
|
|
178
|
+
durable application would save that decision and respect it on later ingestions.
|
|
179
|
+
Removing a fact from the current calculation needn't mean forgetting why it
|
|
180
|
+
was once included.
|
|
181
|
+
|
|
182
|
+
This is useful human involvement: a person can inspect one disagreement, change
|
|
183
|
+
the part that needs judgment, and see what follows.
|
|
184
|
+
|
|
185
|
+
## Follow the uncertainty to the conclusion
|
|
186
|
+
|
|
187
|
+
We can now ask how well this conclusion is supported.
|
|
188
|
+
|
|
189
|
+
For the demonstration, we take the imported list and register as given inputs.
|
|
190
|
+
We assign them a support weight of one for this calculation. That is an explicit
|
|
191
|
+
assumption, not a claim that structured data is infallible and not a model
|
|
192
|
+
probability.
|
|
193
|
+
|
|
194
|
+
The documentary readings remain uncertain. One scores `0.96`, the other `0.87`.
|
|
195
|
+
We use a simple policy: an argument requiring all its facts is only as strong
|
|
196
|
+
as the weakest one.
|
|
197
|
+
|
|
198
|
+
```text
|
|
199
|
+
Ownership argument 0.87
|
|
200
|
+
Oriole is blocked given
|
|
201
|
+
Alder's registered stake is at least 50% given
|
|
202
|
+
Alder holds the stake for Oriole 0.96
|
|
203
|
+
The arrangement is in force 0.87
|
|
204
|
+
|
|
205
|
+
min(1, 1, 0.96, 0.87) = 0.87
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
The number tells us where to look next. Improving the reading of the deed to
|
|
209
|
+
`0.99` would not strengthen this argument. The weaker part is the evidence that
|
|
210
|
+
the arrangement remains in force.
|
|
211
|
+
|
|
212
|
+
Suppose we add a signed supplemental confirmation. Its support for that same
|
|
213
|
+
fact is `0.92`. Our demonstration policy takes the stronger of alternative
|
|
214
|
+
pieces of positive evidence:
|
|
215
|
+
|
|
216
|
+
```text
|
|
217
|
+
Arrangement in force: max(0.87, 0.92) = 0.92
|
|
218
|
+
Ownership argument: min(1, 1, 0.96, 0.92) = 0.92
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
We call this a **support score**. It summarizes the argument under an explicit
|
|
222
|
+
policy. It does not establish a 92% probability that a legal conclusion is
|
|
223
|
+
correct. The runnable example contains a small helper for this calculation;
|
|
224
|
+
it leaves conflicted results unscored rather than hide the disagreement behind
|
|
225
|
+
one number.
|
|
226
|
+
|
|
227
|
+
## The same idea can explain reported causes
|
|
228
|
+
|
|
229
|
+
Consider another question: why did a customer leave?
|
|
230
|
+
|
|
231
|
+
Our customer database can tell us that Cobalt canceled on September 1. That is
|
|
232
|
+
another fact to import directly. An exit interview is different: it says that
|
|
233
|
+
outages, failed onboarding, and billing disputes contributed to the decision,
|
|
234
|
+
but price did not.
|
|
235
|
+
|
|
236
|
+
We ask Jev whether each candidate factor is reported to have contributed to
|
|
237
|
+
that particular cancellation:
|
|
238
|
+
|
|
239
|
+
| Factor | Reading of the interview | Support |
|
|
240
|
+
| ----------- | ----------------------------- | ------- |
|
|
241
|
+
| Reliability | Contributed | 0.94 |
|
|
242
|
+
| Onboarding | Contributed | 0.82 |
|
|
243
|
+
| Billing | Contributed | 0.76 |
|
|
244
|
+
| Price | Explicitly did not contribute | 0.91 |
|
|
245
|
+
| Competition | Not addressed | — |
|
|
246
|
+
|
|
247
|
+
Price and competition are different. There is evidence against one; we simply
|
|
248
|
+
don't know about the other. Several factors can contribute, so their scores
|
|
249
|
+
need not add up to one.
|
|
250
|
+
|
|
251
|
+
We can write rules that group the facts into explanations. If our definition
|
|
252
|
+
of “product breakdown” requires both reliability and onboarding to have
|
|
253
|
+
contributed, the same calculation gives it `min(0.94, 0.82) = 0.82`. A separate
|
|
254
|
+
explanation based on billing has support of `0.76`.
|
|
255
|
+
|
|
256
|
+
Set aside the onboarding evidence in a temporary copy of the case, and the
|
|
257
|
+
product explanation lacks a required fact. The billing explanation still
|
|
258
|
+
holds. The strongest remaining argument scores `0.76`.
|
|
259
|
+
|
|
260
|
+
That shows how the explanation depends on its evidence. It does not show that
|
|
261
|
+
fixing onboarding would reduce churn by six percentage points. We have
|
|
262
|
+
analyzed reported contributions, not estimated the effect of an intervention.
|
|
263
|
+
|
|
264
|
+
## Learn whether the numbers deserve our trust
|
|
265
|
+
|
|
266
|
+
Eventually, reviewed cases and actual outcomes give us a way to evaluate the
|
|
267
|
+
scores. There are two different things we might want to learn.
|
|
268
|
+
|
|
269
|
+
First, **does Jev read the documents correctly?** Reviewers can label whether a
|
|
270
|
+
passage asserts, denies, or says nothing about a claim. Those labels let us
|
|
271
|
+
evaluate and adjust the model's three-way probabilities. We should retain the
|
|
272
|
+
original assessment alongside any adjusted score.
|
|
273
|
+
|
|
274
|
+
Second, **can these signals predict an outcome?** We might use support
|
|
275
|
+
conversations, onboarding notes, and billing records to predict cancellation
|
|
276
|
+
within 30 days. A small statistical model could learn from Jev's assessments,
|
|
277
|
+
structured customer data, and actual cancellation outcomes.
|
|
278
|
+
|
|
279
|
+
These experiments need different labels. Knowing that a customer canceled
|
|
280
|
+
doesn't establish that every proposed reason was correct. And an exit interview
|
|
281
|
+
collected after cancellation cannot predict that same cancellation.
|
|
282
|
+
|
|
283
|
+
For a forward-looking prediction, we need the information available at the time
|
|
284
|
+
and a complete period in which to observe the outcome. We fit on some customers
|
|
285
|
+
and test on other, later cases. If predictions near `0.80` repeatedly come true
|
|
286
|
+
only 60% of the time, they are overconfident. A useful calibration improves
|
|
287
|
+
that correspondence on cases it hasn't seen.
|
|
288
|
+
|
|
289
|
+
This layer is still a design idea. Calibrating individual readings would not
|
|
290
|
+
automatically calibrate the final min/max score, either. We would check that
|
|
291
|
+
separately. The aim is to earn the meaning of a probability through observation,
|
|
292
|
+
rather than obtain it by putting a percent sign next to a number.
|
|
293
|
+
|
|
294
|
+
## Keep the work you've already done
|
|
295
|
+
|
|
296
|
+
The common thread is a place for progress to accumulate.
|
|
297
|
+
|
|
298
|
+
The rule is written down. Structured records enter through ordinary code.
|
|
299
|
+
Documentary interpretations point back to passages. A disagreement has a
|
|
300
|
+
location. A correction has a reason. A score has a calculation.
|
|
301
|
+
|
|
302
|
+
The AI still does valuable work: interpreting material that doesn't arrive as
|
|
303
|
+
neat fields. But its contribution becomes something we can inspect and revise
|
|
304
|
+
in pieces. Each correction improves the case instead of starting another round
|
|
305
|
+
of answer generation.
|
|
306
|
+
|
|
307
|
+
That's the experience we're trying to build with Factbag: an answer you can
|
|
308
|
+
understand well enough to fix, without losing the parts you've already checked.
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
**Try the examples:** run `pnpm --filter @factbag/jev demo` from the repository
|
|
313
|
+
root. The examples use fictional structured records and scripted Jev responses;
|
|
314
|
+
they perform no live sanctions screening or model calls. Evidence review,
|
|
315
|
+
support scoring, and factor analysis are runnable; calibration is a proposed
|
|
316
|
+
next step. See the [example notes](https://github.com/factbag/factbag/tree/main/providers/jev/examples#readme) for the code and its
|
|
317
|
+
scope, or the [package reference](https://github.com/factbag/factbag/blob/main/providers/jev/README.md) for the current API.
|
package/package.json
CHANGED
|
@@ -1,16 +1,104 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@factbag/jev",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
5
|
-
"
|
|
3
|
+
"version": "0.1.0-alpha.7",
|
|
4
|
+
"description": "Lazy AI-assisted classification and evidence resolution for Factbag.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"classification",
|
|
7
|
+
"evidence",
|
|
8
|
+
"ai",
|
|
9
|
+
"rules-engine",
|
|
10
|
+
"typescript"
|
|
11
|
+
],
|
|
6
12
|
"homepage": "https://github.com/factbag/factbag/tree/main/providers/jev#readme",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/factbag/factbag/issues"
|
|
15
|
+
},
|
|
7
16
|
"repository": {
|
|
8
17
|
"type": "git",
|
|
9
18
|
"url": "git+https://github.com/factbag/factbag.git",
|
|
10
19
|
"directory": "providers/jev"
|
|
11
20
|
},
|
|
21
|
+
"license": "Apache-2.0",
|
|
22
|
+
"sideEffects": false,
|
|
23
|
+
"type": "module",
|
|
24
|
+
"files": [
|
|
25
|
+
"dist/public",
|
|
26
|
+
"docs/README.md",
|
|
27
|
+
"CHANGELOG.md",
|
|
28
|
+
"README.md",
|
|
29
|
+
"LICENSE"
|
|
30
|
+
],
|
|
31
|
+
"exports": {
|
|
32
|
+
".": {
|
|
33
|
+
"types": "./dist/public/index.d.ts",
|
|
34
|
+
"import": "./dist/public/index.js"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": "^22.18.0 || ^24.0.0 || ^26.0.0"
|
|
39
|
+
},
|
|
12
40
|
"publishConfig": {
|
|
13
|
-
"access": "public"
|
|
14
|
-
|
|
41
|
+
"access": "public"
|
|
42
|
+
},
|
|
43
|
+
"tsdown": [
|
|
44
|
+
{
|
|
45
|
+
"entry": [
|
|
46
|
+
"src/index.ts"
|
|
47
|
+
],
|
|
48
|
+
"dts": false,
|
|
49
|
+
"sourcemap": true,
|
|
50
|
+
"fixedExtension": false,
|
|
51
|
+
"deps": {
|
|
52
|
+
"neverBundle": true
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"entry": {
|
|
57
|
+
"index": "src/index.ts"
|
|
58
|
+
},
|
|
59
|
+
"outDir": "dist/public",
|
|
60
|
+
"clean": false,
|
|
61
|
+
"dts": true,
|
|
62
|
+
"fixedExtension": false,
|
|
63
|
+
"tsconfig": "tsconfig.public.json",
|
|
64
|
+
"deps": {
|
|
65
|
+
"alwaysBundle": [
|
|
66
|
+
"@factbag/system-one"
|
|
67
|
+
],
|
|
68
|
+
"neverBundle": true,
|
|
69
|
+
"onlyImport": [
|
|
70
|
+
"factbag",
|
|
71
|
+
"@typesafe-ai/sdk"
|
|
72
|
+
]
|
|
73
|
+
},
|
|
74
|
+
"publint": true,
|
|
75
|
+
"attw": {
|
|
76
|
+
"profile": "esm-only",
|
|
77
|
+
"level": "error"
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
],
|
|
81
|
+
"devDependencies": {
|
|
82
|
+
"@factbag/system-one": "0.1.0-next.0",
|
|
83
|
+
"@factbag/tsconfig": "0.0.0",
|
|
84
|
+
"@types/node": "22.20.0",
|
|
85
|
+
"@typesafe-ai/sdk": "0.7.0",
|
|
86
|
+
"msw": "2.15.0",
|
|
87
|
+
"tsx": "4.23.15",
|
|
88
|
+
"typescript": "7.0.2",
|
|
89
|
+
"vitest": "5.0.5"
|
|
90
|
+
},
|
|
91
|
+
"peerDependencies": {
|
|
92
|
+
"factbag": "0.1.0-alpha.7",
|
|
93
|
+
"@typesafe-ai/sdk": "^0.7.0"
|
|
94
|
+
},
|
|
95
|
+
"scripts": {
|
|
96
|
+
"api-report": "api-extractor run --local",
|
|
97
|
+
"api-report:check": "api-extractor run",
|
|
98
|
+
"build": "tsdown && tsc -p tsconfig.build.json --emitDeclarationOnly",
|
|
99
|
+
"demo": "tsx examples/run.ts",
|
|
100
|
+
"demo:staged": "tsx examples/staged-comparison.ts",
|
|
101
|
+
"test": "vitest run",
|
|
102
|
+
"typecheck": "tsc --noEmit"
|
|
15
103
|
}
|
|
16
|
-
}
|
|
104
|
+
}
|