@jini-ai/core 0.1.0
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/LICENSE +201 -0
- package/dist/api-token-auth.d.ts +28 -0
- package/dist/api-token-auth.d.ts.map +1 -0
- package/dist/api-token-auth.js +30 -0
- package/dist/api-token-auth.js.map +1 -0
- package/dist/bindings.d.ts +18 -0
- package/dist/bindings.d.ts.map +1 -0
- package/dist/bindings.js +41 -0
- package/dist/bindings.js.map +1 -0
- package/dist/compose.typecheck.d.ts +2 -0
- package/dist/compose.typecheck.d.ts.map +1 -0
- package/dist/compose.typecheck.js +29 -0
- package/dist/compose.typecheck.js.map +1 -0
- package/dist/daemon.d.ts +40 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +37 -0
- package/dist/daemon.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/internal.d.ts +36 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +35 -0
- package/dist/internal.js.map +1 -0
- package/dist/origin-validation.d.ts +63 -0
- package/dist/origin-validation.d.ts.map +1 -0
- package/dist/origin-validation.js +198 -0
- package/dist/origin-validation.js.map +1 -0
- package/dist/pack.d.ts +26 -0
- package/dist/pack.d.ts.map +1 -0
- package/dist/pack.js +4 -0
- package/dist/pack.js.map +1 -0
- package/dist/principal.d.ts +16 -0
- package/dist/principal.d.ts.map +1 -0
- package/dist/principal.js +2 -0
- package/dist/principal.js.map +1 -0
- package/dist/redact.d.ts +48 -0
- package/dist/redact.d.ts.map +1 -0
- package/dist/redact.js +190 -0
- package/dist/redact.js.map +1 -0
- package/dist/token.d.ts +22 -0
- package/dist/token.d.ts.map +1 -0
- package/dist/token.js +7 -0
- package/dist/token.js.map +1 -0
- package/dist/tool-registry.d.ts +114 -0
- package/dist/tool-registry.d.ts.map +1 -0
- package/dist/tool-registry.js +43 -0
- package/dist/tool-registry.js.map +1 -0
- package/dist/tool-tokens.d.ts +3 -0
- package/dist/tool-tokens.d.ts.map +1 -0
- package/dist/tool-tokens.js +10 -0
- package/dist/tool-tokens.js.map +1 -0
- package/package.json +48 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token.js","sourceRoot":"","sources":["../src/token.ts"],"names":[],"mappings":"AAkBA,MAAM,UAAU,KAAK,CAAsC,EAAM,EAAE,OAA6B,EAAE;IAChG,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,SAAS,CACvB,EAAM,EACN,OAA6B,EAAE;IAE/B,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC;AACjE,CAAC"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ToolRegistry` — the registration half of the tool-execution boundary
|
|
3
|
+
* (extraction-plan.md §2.5 / §8 task 6). Tools are registered as
|
|
4
|
+
* `{descriptor, handler, policy}` triples; the registry's *public* surface
|
|
5
|
+
* (this file's `ToolRegistry` interface, and everything re-exported from
|
|
6
|
+
* this package's root `index.ts`) exposes only `ToolDescriptor`s —
|
|
7
|
+
* `register`/`has`/`list`. It never exposes a way to retrieve a `handler`
|
|
8
|
+
* or `policy` back out.
|
|
9
|
+
*
|
|
10
|
+
* That's the load-bearing invariant this task is named after: "handlers
|
|
11
|
+
* never publicly retrievable (routes/agents can't bypass authz)." A route
|
|
12
|
+
* or an agent holding a `ToolRegistry` reference can enumerate what's
|
|
13
|
+
* available and check membership, but the only way to actually *run* a
|
|
14
|
+
* tool is through `@jini-ai/daemon`'s `ToolExecutor`, which is the sole
|
|
15
|
+
* consumer of {@link getToolRegistration} — a function deliberately
|
|
16
|
+
* exported from `./internal.js` (a package-internal entry point, see this
|
|
17
|
+
* package's `package.json` `exports` map and `source-map.md`) rather than
|
|
18
|
+
* from the public `index.ts` barrel. Every other caller of
|
|
19
|
+
* `@jini-ai/core`'s default entry point gets descriptors only.
|
|
20
|
+
*/
|
|
21
|
+
import type { Principal } from './principal.js';
|
|
22
|
+
/** A structural run reference — anything with a stable `id` satisfies this (e.g. `@jini-ai/protocol`'s `RunStatus`). No import needed to satisfy it; see the module doc. */
|
|
23
|
+
export interface RunRef {
|
|
24
|
+
readonly id: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The public, non-secret shape of a registered tool. Never carries the
|
|
28
|
+
* handler or policy — those are only reachable via {@link getToolRegistration}.
|
|
29
|
+
*/
|
|
30
|
+
export interface ToolDescriptor {
|
|
31
|
+
readonly id: string;
|
|
32
|
+
readonly description?: string;
|
|
33
|
+
/**
|
|
34
|
+
* JSON-Schema-shaped description of this tool's accepted input, carried as `unknown` because the
|
|
35
|
+
* kernel neither parses nor validates it — a schema dialect is a consumer concern, and taking a
|
|
36
|
+
* validator dependency here would put one in every package that touches a registry.
|
|
37
|
+
*
|
|
38
|
+
* It exists because *every* discovery mechanism needs it and nothing else in the kernel can
|
|
39
|
+
* supply it: a caller that can enumerate `ToolRegistry.list()` still cannot tell an agent what
|
|
40
|
+
* arguments a tool takes, which reduces discovery to guess-and-check against an opaque id.
|
|
41
|
+
* Optional and additive, so no existing registration changes shape.
|
|
42
|
+
*/
|
|
43
|
+
readonly inputSchema?: unknown;
|
|
44
|
+
/** When true, `ToolExecutor` asks the transport's `ExecutionDelegate.onConfirm` before running, in addition to authorization. */
|
|
45
|
+
readonly requiresConfirmation?: boolean;
|
|
46
|
+
/** Milliseconds before `ToolExecutor` aborts an in-flight call and reports `'timed-out'`. Omit for no timeout. */
|
|
47
|
+
readonly timeoutMs?: number;
|
|
48
|
+
/** Byte/character ceiling `ToolExecutor` truncates string output to. Omit for no truncation. */
|
|
49
|
+
readonly maxOutputBytes?: number;
|
|
50
|
+
}
|
|
51
|
+
/** What a `ToolHandler` receives — everything it needs and nothing it could use to bypass the gate (no registry access, no other tools' state). */
|
|
52
|
+
export interface ToolExecutionContext {
|
|
53
|
+
/** The id `ToolExecutor` assigned this call — for the handler's own logging/correlation; carries no authority (the gate already ran before the handler is invoked). */
|
|
54
|
+
readonly executionId: string;
|
|
55
|
+
readonly principal: Principal;
|
|
56
|
+
readonly run: RunRef;
|
|
57
|
+
readonly input: unknown;
|
|
58
|
+
readonly signal: AbortSignal;
|
|
59
|
+
}
|
|
60
|
+
/** Runs the tool's actual side effect. Only ever invoked by `ToolExecutor`, never called directly by a route/agent holding the registry. */
|
|
61
|
+
export type ToolHandler = (ctx: ToolExecutionContext) => Promise<unknown>;
|
|
62
|
+
export type AuthorizationDecision = 'allow' | 'deny';
|
|
63
|
+
export interface ToolAuthorizationContext {
|
|
64
|
+
readonly principal: Principal;
|
|
65
|
+
readonly run: RunRef;
|
|
66
|
+
readonly tool: ToolDescriptor;
|
|
67
|
+
readonly input: unknown;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* A tool's admission-control rule: given who's calling, on which run, with
|
|
71
|
+
* what input, is this call allowed at all? Distinct from *confirmation*
|
|
72
|
+
* (`ToolDescriptor.requiresConfirmation`, a per-call human "are you sure"
|
|
73
|
+
* gate `ToolExecutor` applies afterward) — a policy answers "is this
|
|
74
|
+
* principal permitted to use this tool", a confirmation answers "does the
|
|
75
|
+
* user want to proceed with this specific invocation right now."
|
|
76
|
+
*/
|
|
77
|
+
export interface ToolPolicy {
|
|
78
|
+
authorize(ctx: ToolAuthorizationContext): AuthorizationDecision | Promise<AuthorizationDecision>;
|
|
79
|
+
}
|
|
80
|
+
export interface ToolRegistration {
|
|
81
|
+
readonly descriptor: ToolDescriptor;
|
|
82
|
+
readonly handler: ToolHandler;
|
|
83
|
+
readonly policy: ToolPolicy;
|
|
84
|
+
}
|
|
85
|
+
/** The public registration/enumeration surface. See the module doc for why `handler`/`policy` never appear here. */
|
|
86
|
+
export interface ToolRegistry {
|
|
87
|
+
/** @throws If `registration.descriptor.id` is already registered — re-registration must be explicit (unregister is not exposed; this registry is append-only by design, matching the kernel's "tools are registered once at composition time" model). */
|
|
88
|
+
register(registration: ToolRegistration): void;
|
|
89
|
+
has(toolId: string): boolean;
|
|
90
|
+
/** Descriptors only, in registration order. Never the underlying handlers/policies. */
|
|
91
|
+
list(): readonly ToolDescriptor[];
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Creates an empty, append-only `ToolRegistry`.
|
|
95
|
+
*
|
|
96
|
+
* @returns A `ToolRegistry` whose backing `{descriptor, handler, policy}`
|
|
97
|
+
* map is held in a module-private `WeakMap` keyed by the returned instance
|
|
98
|
+
* — reachable only via {@link getToolRegistration}, not through any method
|
|
99
|
+
* on the returned object itself.
|
|
100
|
+
* @complexity `register`/`has` O(1); `list` O(n) in registered tool count.
|
|
101
|
+
* @overallScore 100/100
|
|
102
|
+
*/
|
|
103
|
+
export declare function createToolRegistry(): ToolRegistry;
|
|
104
|
+
/**
|
|
105
|
+
* Package-internal escape hatch: resolves a tool's full `{descriptor,
|
|
106
|
+
* handler, policy}` registration. Exported only from `./internal.js` (see
|
|
107
|
+
* this package's `package.json` `exports` map) — `@jini-ai/daemon`'s
|
|
108
|
+
* `ToolExecutor` is the one and only intended caller. Not re-exported from
|
|
109
|
+
* `index.ts`, so it never reaches `@jini-ai/core`'s public consumers.
|
|
110
|
+
*
|
|
111
|
+
* @internal
|
|
112
|
+
*/
|
|
113
|
+
export declare function getToolRegistration(registry: ToolRegistry, toolId: string): ToolRegistration | undefined;
|
|
114
|
+
//# sourceMappingURL=tool-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-registry.d.ts","sourceRoot":"","sources":["../src/tool-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,4KAA4K;AAC5K,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;;;;;OASG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,iIAAiI;IACjI,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IACxC,kHAAkH;IAClH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,gGAAgG;IAChG,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAED,mJAAmJ;AACnJ,MAAM,WAAW,oBAAoB;IACnC,uKAAuK;IACvK,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC9B;AAED,4IAA4I;AAC5I,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE,oBAAoB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAE1E,MAAM,MAAM,qBAAqB,GAAG,OAAO,GAAG,MAAM,CAAC;AAErD,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,UAAU;IACzB,SAAS,CAAC,GAAG,EAAE,wBAAwB,GAAG,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;CAClG;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;CAC7B;AAED,oHAAoH;AACpH,MAAM,WAAW,YAAY;IAC3B,yPAAyP;IACzP,QAAQ,CAAC,YAAY,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC/C,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IAC7B,uFAAuF;IACvF,IAAI,IAAI,SAAS,cAAc,EAAE,CAAC;CACnC;AAID;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,IAAI,YAAY,CAoBjD;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAExG"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const registrationsByRegistry = new WeakMap();
|
|
2
|
+
/**
|
|
3
|
+
* Creates an empty, append-only `ToolRegistry`.
|
|
4
|
+
*
|
|
5
|
+
* @returns A `ToolRegistry` whose backing `{descriptor, handler, policy}`
|
|
6
|
+
* map is held in a module-private `WeakMap` keyed by the returned instance
|
|
7
|
+
* — reachable only via {@link getToolRegistration}, not through any method
|
|
8
|
+
* on the returned object itself.
|
|
9
|
+
* @complexity `register`/`has` O(1); `list` O(n) in registered tool count.
|
|
10
|
+
* @overallScore 100/100
|
|
11
|
+
*/
|
|
12
|
+
export function createToolRegistry() {
|
|
13
|
+
const registrations = new Map();
|
|
14
|
+
const registry = {
|
|
15
|
+
register(registration) {
|
|
16
|
+
if (registrations.has(registration.descriptor.id)) {
|
|
17
|
+
throw new Error(`ToolRegistry: tool "${registration.descriptor.id}" is already registered`);
|
|
18
|
+
}
|
|
19
|
+
registrations.set(registration.descriptor.id, registration);
|
|
20
|
+
},
|
|
21
|
+
has(toolId) {
|
|
22
|
+
return registrations.has(toolId);
|
|
23
|
+
},
|
|
24
|
+
list() {
|
|
25
|
+
return Array.from(registrations.values(), (r) => r.descriptor);
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
registrationsByRegistry.set(registry, registrations);
|
|
29
|
+
return registry;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Package-internal escape hatch: resolves a tool's full `{descriptor,
|
|
33
|
+
* handler, policy}` registration. Exported only from `./internal.js` (see
|
|
34
|
+
* this package's `package.json` `exports` map) — `@jini-ai/daemon`'s
|
|
35
|
+
* `ToolExecutor` is the one and only intended caller. Not re-exported from
|
|
36
|
+
* `index.ts`, so it never reaches `@jini-ai/core`'s public consumers.
|
|
37
|
+
*
|
|
38
|
+
* @internal
|
|
39
|
+
*/
|
|
40
|
+
export function getToolRegistration(registry, toolId) {
|
|
41
|
+
return registrationsByRegistry.get(registry)?.get(toolId);
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=tool-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-registry.js","sourceRoot":"","sources":["../src/tool-registry.ts"],"names":[],"mappings":"AAsGA,MAAM,uBAAuB,GAAG,IAAI,OAAO,EAA+C,CAAC;AAE3F;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB;IAChC,MAAM,aAAa,GAAG,IAAI,GAAG,EAA4B,CAAC;IAE1D,MAAM,QAAQ,GAAiB;QAC7B,QAAQ,CAAC,YAA8B;YACrC,IAAI,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC;gBAClD,MAAM,IAAI,KAAK,CAAC,uBAAuB,YAAY,CAAC,UAAU,CAAC,EAAE,yBAAyB,CAAC,CAAC;YAC9F,CAAC;YACD,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC;QAC9D,CAAC;QACD,GAAG,CAAC,MAAc;YAChB,OAAO,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACnC,CAAC;QACD,IAAI;YACF,OAAO,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QACjE,CAAC;KACF,CAAC;IAEF,uBAAuB,CAAC,GAAG,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IACrD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAC,QAAsB,EAAE,MAAc;IACxE,OAAO,uBAAuB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;AAC5D,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-tokens.d.ts","sourceRoot":"","sources":["../src/tool-tokens.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,eAAO,MAAM,iBAAiB,kDAA2C,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@jini-ai/core` DI token for `ToolRegistry` — defined alongside the service
|
|
3
|
+
* it names, per this package's own composition contract (`token.ts`) and
|
|
4
|
+
* mirroring `@jini-ai/daemon/src/tokens.ts`'s identical rationale for
|
|
5
|
+
* `RunLifecycle`/`EventLog`: a kernel-service token lives in the package
|
|
6
|
+
* that owns the service, not in a central registry.
|
|
7
|
+
*/
|
|
8
|
+
import { token } from './token.js';
|
|
9
|
+
export const ToolRegistryToken = token('jini.toolRegistry');
|
|
10
|
+
//# sourceMappingURL=tool-tokens.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-tokens.js","sourceRoot":"","sources":["../src/tool-tokens.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGnC,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,CAAe,mBAAmB,CAAC,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@jini-ai/core",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"license": "Apache-2.0",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/AINSEP/Jini.git",
|
|
8
|
+
"directory": "packages/core"
|
|
9
|
+
},
|
|
10
|
+
"jini": {
|
|
11
|
+
"domain": "engine",
|
|
12
|
+
"kind": "kernel",
|
|
13
|
+
"runtime": "universal",
|
|
14
|
+
"admission": "locked"
|
|
15
|
+
},
|
|
16
|
+
"type": "module",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"import": "./dist/index.js"
|
|
21
|
+
},
|
|
22
|
+
"./internal": {
|
|
23
|
+
"types": "./dist/internal.d.ts",
|
|
24
|
+
"import": "./dist/internal.js"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist",
|
|
29
|
+
"!dist/**/*.test.js",
|
|
30
|
+
"!dist/**/*.test.d.ts",
|
|
31
|
+
"!dist/**/*.test.js.map",
|
|
32
|
+
"!dist/**/*.test.d.ts.map",
|
|
33
|
+
"!dist/**/__tests__/**"
|
|
34
|
+
],
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public",
|
|
37
|
+
"registry": "https://registry.npmjs.org"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@vitest/coverage-v8": "^2.1.9"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "tsc -p tsconfig.json",
|
|
44
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
45
|
+
"test": "vitest run",
|
|
46
|
+
"test:coverage": "vitest run --coverage"
|
|
47
|
+
}
|
|
48
|
+
}
|