@medicine-wheel/gap-analysis 0.5.3
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 +81 -0
- package/dist/index.d.ts +80 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +88 -0
- package/dist/index.js.map +1 -0
- package/package.json +45 -0
package/README.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# @medicine-wheel/gap-analysis
|
|
2
|
+
|
|
3
|
+
Problem-solving, built properly and without apology.
|
|
4
|
+
|
|
5
|
+
> [!WARNING]
|
|
6
|
+
> **Experimental alpha.** Part of the Medicine Wheel Developer Suite, which is
|
|
7
|
+
> under active development. APIs change between patch versions and all packages
|
|
8
|
+
> move in lockstep — pin exact versions. See
|
|
9
|
+
> [ALPHA.md](https://github.com/jgwill/medicine-wheel/blob/main/ALPHA.md).
|
|
10
|
+
|
|
11
|
+
## Why it exists
|
|
12
|
+
|
|
13
|
+
Sometimes the forest is on fire. Digitally too. When something worked and
|
|
14
|
+
stopped working, closing the difference between the current state and the prior
|
|
15
|
+
one is the **right** move — oscillating back to a baseline is the goal when you
|
|
16
|
+
are below the baseline.
|
|
17
|
+
|
|
18
|
+
Work like that deserves a real instrument rather than a euphemism, so this
|
|
19
|
+
package is built as a first-class citizen of the suite and not smuggled in under
|
|
20
|
+
a nicer name.
|
|
21
|
+
|
|
22
|
+
## The question at the door
|
|
23
|
+
|
|
24
|
+
Every analysis carries an orientation reading taken when it was opened, via
|
|
25
|
+
`@medicine-wheel/creative-orientation`. The question is always the same: *is a
|
|
26
|
+
prior state actually being restored?*
|
|
27
|
+
|
|
28
|
+
Opening an analysis **requires a baseline with evidence**. That requirement is
|
|
29
|
+
the whole point — it is the thing that separates a fire from a creating act, and
|
|
30
|
+
it cannot be satisfied by a feeling of urgency.
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
import { openGapAnalysis, addStep, doorAdvice } from '@medicine-wheel/gap-analysis';
|
|
34
|
+
|
|
35
|
+
let analysis = openGapAnalysis(
|
|
36
|
+
{ description: 'the published image matched the published packages',
|
|
37
|
+
evidence: 'true through 0.5.0, tagged 2026-07-17' },
|
|
38
|
+
{ description: 'newest versioned image tag is 0.5.0; npm is at 0.5.2; 0.5.1 has no image',
|
|
39
|
+
source: 'Docker Hub tags API, read 2026-07-25' },
|
|
40
|
+
'the image no longer tracks npm because building it depends on a human remembering a flag',
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
doorAdvice(analysis); // null — the situation and the instrument agree
|
|
44
|
+
|
|
45
|
+
analysis = addStep(analysis, {
|
|
46
|
+
action: 'build the image from the tag in CI rather than from release.sh',
|
|
47
|
+
verifiedBy: 'a v* tag push produces :app and :<version> without anyone running anything',
|
|
48
|
+
});
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## It advises; it never refuses
|
|
52
|
+
|
|
53
|
+
If you open an analysis without evidence for the baseline, you get the analysis
|
|
54
|
+
**and** advice saying the routing rests on a feeling. You are not blocked. A
|
|
55
|
+
package that refuses is a package you learn to route around, and sometimes the
|
|
56
|
+
caller knows something the check does not.
|
|
57
|
+
|
|
58
|
+
## Steps must be verifiable
|
|
59
|
+
|
|
60
|
+
`addStep` rejects a step with no `verifiedBy`. An elimination step you cannot
|
|
61
|
+
check is a wish; the fire is out only when something says so.
|
|
62
|
+
|
|
63
|
+
## Where it sits
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
creative-orientation ......... the gate
|
|
67
|
+
├── gap-analysis ......... you are here — the fire path
|
|
68
|
+
└── structural-tension ... the advancing path
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Gap analysis is a borrowed instrument. It is genuinely available, and it is not
|
|
72
|
+
the foundation — the orientation question comes first, and this package reports
|
|
73
|
+
to it rather than the reverse.
|
|
74
|
+
|
|
75
|
+
## Status
|
|
76
|
+
|
|
77
|
+
First release. Small on purpose.
|
|
78
|
+
|
|
79
|
+
## License
|
|
80
|
+
|
|
81
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @medicine-wheel/gap-analysis
|
|
3
|
+
*
|
|
4
|
+
* The fire path, built properly and without apology.
|
|
5
|
+
*
|
|
6
|
+
* When something worked and stopped working, closing the difference between
|
|
7
|
+
* current and prior state is the correct move. Oscillation back to a baseline
|
|
8
|
+
* is the goal when you are below the baseline. This package exists so that
|
|
9
|
+
* work has a real instrument instead of a euphemism.
|
|
10
|
+
*
|
|
11
|
+
* It carries one question at its door — is a prior state actually being
|
|
12
|
+
* restored? — and asks it through `@medicine-wheel/creative-orientation`.
|
|
13
|
+
* It **advises and proceeds**. It never refuses. A package that blocks you is
|
|
14
|
+
* a package you learn to route around.
|
|
15
|
+
*
|
|
16
|
+
* @packageDocumentation
|
|
17
|
+
*/
|
|
18
|
+
import { type OrientationReading } from '@medicine-wheel/creative-orientation';
|
|
19
|
+
export interface Baseline {
|
|
20
|
+
/** The state being restored, described concretely. */
|
|
21
|
+
description: string;
|
|
22
|
+
/** Evidence it existed — a date, a commit, a reading, a receipt. */
|
|
23
|
+
evidence: string;
|
|
24
|
+
}
|
|
25
|
+
export interface Observation {
|
|
26
|
+
/** What is true now, stated as measurement rather than interpretation. */
|
|
27
|
+
description: string;
|
|
28
|
+
/** Where this reading came from. */
|
|
29
|
+
source?: string;
|
|
30
|
+
}
|
|
31
|
+
export interface EliminationStep {
|
|
32
|
+
action: string;
|
|
33
|
+
/** How you will know this step worked. */
|
|
34
|
+
verifiedBy: string;
|
|
35
|
+
done?: boolean;
|
|
36
|
+
}
|
|
37
|
+
export interface GapAnalysis {
|
|
38
|
+
id: string;
|
|
39
|
+
baseline: Baseline;
|
|
40
|
+
current: Observation;
|
|
41
|
+
/** What is missing or wrong, derived from the two states above. */
|
|
42
|
+
difference: string;
|
|
43
|
+
rootCause?: string;
|
|
44
|
+
steps: EliminationStep[];
|
|
45
|
+
opened: string;
|
|
46
|
+
/**
|
|
47
|
+
* The orientation reading taken when this analysis was opened. Kept on the
|
|
48
|
+
* record so a later reader can see whether the instrument suited the
|
|
49
|
+
* situation, rather than having to reconstruct it.
|
|
50
|
+
*/
|
|
51
|
+
orientation: OrientationReading;
|
|
52
|
+
}
|
|
53
|
+
export interface OpenGapOptions {
|
|
54
|
+
id?: string;
|
|
55
|
+
idFactory?: () => string;
|
|
56
|
+
timestamp?: string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Open a gap analysis.
|
|
60
|
+
*
|
|
61
|
+
* A baseline with evidence is required, and that requirement is the whole
|
|
62
|
+
* point: it is the question that separates a fire from a creating act. If you
|
|
63
|
+
* cannot name a state that existed, the returned analysis carries advice
|
|
64
|
+
* saying so — and is still returned, because the caller may know something
|
|
65
|
+
* this check does not.
|
|
66
|
+
*/
|
|
67
|
+
export declare function openGapAnalysis(baseline: Baseline, current: Observation, difference: string, options?: OpenGapOptions): GapAnalysis;
|
|
68
|
+
/** Add a step, with the check that makes it verifiable rather than hopeful. */
|
|
69
|
+
export declare function addStep(analysis: GapAnalysis, step: EliminationStep): GapAnalysis;
|
|
70
|
+
export declare function markDone(analysis: GapAnalysis, action: string): GapAnalysis;
|
|
71
|
+
/** Closed when every step is done. Says nothing about whether it was the right analysis. */
|
|
72
|
+
export declare function isClosed(analysis: GapAnalysis): boolean;
|
|
73
|
+
/**
|
|
74
|
+
* The advice to surface at the door, if any.
|
|
75
|
+
*
|
|
76
|
+
* Returns null when the situation and the instrument agree — advice on
|
|
77
|
+
* correctly-framed work is noise, and noise is how checks get switched off.
|
|
78
|
+
*/
|
|
79
|
+
export declare function doorAdvice(analysis: GapAnalysis): string | null;
|
|
80
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAGL,KAAK,kBAAkB,EAExB,MAAM,sCAAsC,CAAC;AAE9C,MAAM,WAAW,QAAQ;IACvB,sDAAsD;IACtD,WAAW,EAAE,MAAM,CAAC;IACpB,oEAAoE;IACpE,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,0EAA0E;IAC1E,WAAW,EAAE,MAAM,CAAC;IACpB,oCAAoC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,WAAW,CAAC;IACrB,mEAAmE;IACnE,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,WAAW,EAAE,kBAAkB,CAAC;CACjC;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAMD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,WAAW,EACpB,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,cAAmB,GAC3B,WAAW,CA0Bb;AAED,+EAA+E;AAC/E,wBAAgB,OAAO,CAAC,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe,GAAG,WAAW,CAQjF;AAED,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,CAK3E;AAED,4FAA4F;AAC5F,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,WAAW,GAAG,OAAO,CAEvD;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI,CAE/D"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.openGapAnalysis = openGapAnalysis;
|
|
4
|
+
exports.addStep = addStep;
|
|
5
|
+
exports.markDone = markDone;
|
|
6
|
+
exports.isClosed = isClosed;
|
|
7
|
+
exports.doorAdvice = doorAdvice;
|
|
8
|
+
/**
|
|
9
|
+
* @medicine-wheel/gap-analysis
|
|
10
|
+
*
|
|
11
|
+
* The fire path, built properly and without apology.
|
|
12
|
+
*
|
|
13
|
+
* When something worked and stopped working, closing the difference between
|
|
14
|
+
* current and prior state is the correct move. Oscillation back to a baseline
|
|
15
|
+
* is the goal when you are below the baseline. This package exists so that
|
|
16
|
+
* work has a real instrument instead of a euphemism.
|
|
17
|
+
*
|
|
18
|
+
* It carries one question at its door — is a prior state actually being
|
|
19
|
+
* restored? — and asks it through `@medicine-wheel/creative-orientation`.
|
|
20
|
+
* It **advises and proceeds**. It never refuses. A package that blocks you is
|
|
21
|
+
* a package you learn to route around.
|
|
22
|
+
*
|
|
23
|
+
* @packageDocumentation
|
|
24
|
+
*/
|
|
25
|
+
const creative_orientation_1 = require("@medicine-wheel/creative-orientation");
|
|
26
|
+
function defaultId() {
|
|
27
|
+
return `gap:${Date.now()}:${Math.random().toString(36).slice(2, 8)}`;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Open a gap analysis.
|
|
31
|
+
*
|
|
32
|
+
* A baseline with evidence is required, and that requirement is the whole
|
|
33
|
+
* point: it is the question that separates a fire from a creating act. If you
|
|
34
|
+
* cannot name a state that existed, the returned analysis carries advice
|
|
35
|
+
* saying so — and is still returned, because the caller may know something
|
|
36
|
+
* this check does not.
|
|
37
|
+
*/
|
|
38
|
+
function openGapAnalysis(baseline, current, difference, options = {}) {
|
|
39
|
+
if (!baseline.description?.trim()) {
|
|
40
|
+
throw new Error('A gap analysis needs a baseline — the state you are restoring. Without one there is ' +
|
|
41
|
+
'nothing to close toward, and the situation is a creating act rather than a repair.');
|
|
42
|
+
}
|
|
43
|
+
if (!current.description?.trim()) {
|
|
44
|
+
throw new Error('A gap analysis needs an observation of what is true now.');
|
|
45
|
+
}
|
|
46
|
+
const claim = {
|
|
47
|
+
outcome: difference,
|
|
48
|
+
restores: baseline.description,
|
|
49
|
+
evidence: baseline.evidence,
|
|
50
|
+
};
|
|
51
|
+
return {
|
|
52
|
+
id: options.id ?? (options.idFactory ? options.idFactory() : defaultId()),
|
|
53
|
+
baseline,
|
|
54
|
+
current,
|
|
55
|
+
difference,
|
|
56
|
+
steps: [],
|
|
57
|
+
opened: options.timestamp ?? new Date().toISOString(),
|
|
58
|
+
orientation: (0, creative_orientation_1.readOrientation)(claim),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/** Add a step, with the check that makes it verifiable rather than hopeful. */
|
|
62
|
+
function addStep(analysis, step) {
|
|
63
|
+
if (!step.verifiedBy?.trim()) {
|
|
64
|
+
throw new Error(`Step "${step.action}" has no verification. An elimination step you cannot check is a ` +
|
|
65
|
+
'wish; the fire is out only when something says so.');
|
|
66
|
+
}
|
|
67
|
+
return { ...analysis, steps: [...analysis.steps, step] };
|
|
68
|
+
}
|
|
69
|
+
function markDone(analysis, action) {
|
|
70
|
+
return {
|
|
71
|
+
...analysis,
|
|
72
|
+
steps: analysis.steps.map(s => (s.action === action ? { ...s, done: true } : s)),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/** Closed when every step is done. Says nothing about whether it was the right analysis. */
|
|
76
|
+
function isClosed(analysis) {
|
|
77
|
+
return analysis.steps.length > 0 && analysis.steps.every(s => s.done === true);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* The advice to surface at the door, if any.
|
|
81
|
+
*
|
|
82
|
+
* Returns null when the situation and the instrument agree — advice on
|
|
83
|
+
* correctly-framed work is noise, and noise is how checks get switched off.
|
|
84
|
+
*/
|
|
85
|
+
function doorAdvice(analysis) {
|
|
86
|
+
return (0, creative_orientation_1.worthSaying)(analysis.orientation) ? analysis.orientation.advice ?? null : null;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAiFA,0CA+BC;AAGD,0BAQC;AAED,4BAKC;AAGD,4BAEC;AAQD,gCAEC;AAjJD;;;;;;;;;;;;;;;;GAgBG;AACH,+EAK8C;AA8C9C,SAAS,SAAS;IAChB,OAAO,OAAO,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;AACvE,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,eAAe,CAC7B,QAAkB,EAClB,OAAoB,EACpB,UAAkB,EAClB,UAA0B,EAAE;IAE5B,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,IAAI,EAAE,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CACb,sFAAsF;YACpF,oFAAoF,CACvF,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,EAAE,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC9E,CAAC;IAED,MAAM,KAAK,GAAmB;QAC5B,OAAO,EAAE,UAAU;QACnB,QAAQ,EAAE,QAAQ,CAAC,WAAW;QAC9B,QAAQ,EAAE,QAAQ,CAAC,QAAQ;KAC5B,CAAC;IAEF,OAAO;QACL,EAAE,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;QACzE,QAAQ;QACR,OAAO;QACP,UAAU;QACV,KAAK,EAAE,EAAE;QACT,MAAM,EAAE,OAAO,CAAC,SAAS,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACrD,WAAW,EAAE,IAAA,sCAAe,EAAC,KAAK,CAAC;KACpC,CAAC;AACJ,CAAC;AAED,+EAA+E;AAC/E,SAAgB,OAAO,CAAC,QAAqB,EAAE,IAAqB;IAClE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CACb,SAAS,IAAI,CAAC,MAAM,mEAAmE;YACrF,oDAAoD,CACvD,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,GAAG,QAAQ,EAAE,KAAK,EAAE,CAAC,GAAG,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC;AAC3D,CAAC;AAED,SAAgB,QAAQ,CAAC,QAAqB,EAAE,MAAc;IAC5D,OAAO;QACL,GAAG,QAAQ;QACX,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;KACjF,CAAC;AACJ,CAAC;AAED,4FAA4F;AAC5F,SAAgB,QAAQ,CAAC,QAAqB;IAC5C,OAAO,QAAQ,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AACjF,CAAC;AAED;;;;;GAKG;AACH,SAAgB,UAAU,CAAC,QAAqB;IAC9C,OAAO,IAAA,kCAAW,EAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACxF,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@medicine-wheel/gap-analysis",
|
|
3
|
+
"version": "0.5.3",
|
|
4
|
+
"description": "Problem-solving done properly — baseline, observation, difference, elimination steps — with the orientation question asked at its door rather than assumed.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"require": "./dist/index.js",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"sideEffects": false,
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"README.md"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsc",
|
|
22
|
+
"clean": "rm -rf dist",
|
|
23
|
+
"prepublishOnly": "npm run clean && npm run build"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"medicine-wheel",
|
|
27
|
+
"gap-analysis",
|
|
28
|
+
"problem-solving",
|
|
29
|
+
"root-cause",
|
|
30
|
+
"incident"
|
|
31
|
+
],
|
|
32
|
+
"author": "jgwill",
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "git+https://github.com/jgwill/medicine-wheel.git",
|
|
37
|
+
"directory": "src/gap-analysis"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"@medicine-wheel/creative-orientation": "^0.5.3"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"typescript": "^5.7.0"
|
|
44
|
+
}
|
|
45
|
+
}
|