@sweny-ai/core 0.1.106 → 0.1.108
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/dist/executor.js +25 -1
- package/dist/mcp-catalog.js +4 -1
- package/dist/schema.d.ts +12 -5
- package/dist/schema.js +46 -4
- package/dist/source-resolver.d.ts +7 -0
- package/dist/source-resolver.js +8 -1
- package/dist/templates.d.ts +9 -1
- package/dist/templates.js +35 -5
- package/package.json +6 -2
package/dist/executor.js
CHANGED
|
@@ -742,6 +742,23 @@ async function resolveNext(workflow, current, results, input, claude, observer,
|
|
|
742
742
|
// Check for a default (unconditional) edge among conditionals
|
|
743
743
|
const defaultEdge = outEdges.find((e) => !e.when);
|
|
744
744
|
const conditionalEdges = outEdges.filter((e) => e.when);
|
|
745
|
+
// Defense-in-depth for AMBIGUOUS_EDGES (rejected by validateWorkflow): with
|
|
746
|
+
// no conditional edges there is nothing for the route evaluator to decide.
|
|
747
|
+
// Follow the (first) unconditional edge directly and skip the no-op
|
|
748
|
+
// claude.evaluate call. validateWorkflow already rejects 2+ unconditional
|
|
749
|
+
// edges, so a well-formed workflow reaching here has exactly one default.
|
|
750
|
+
if (conditionalEdges.length === 0 && defaultEdge) {
|
|
751
|
+
if (outEdges.length > 1) {
|
|
752
|
+
logger?.warn(` route eval: node '${current}' has ${outEdges.length} unconditional out-edges; following '${defaultEdge.to}' ` +
|
|
753
|
+
`and ignoring the rest. Add 'when' clauses to make routing deterministic (see AMBIGUOUS_EDGES).`, { node: current });
|
|
754
|
+
}
|
|
755
|
+
if (edgeCounts) {
|
|
756
|
+
const key = `${current}→${defaultEdge.to}`;
|
|
757
|
+
edgeCounts.set(key, (edgeCounts.get(key) ?? 0) + 1);
|
|
758
|
+
}
|
|
759
|
+
safeObserve(observer, { type: "route", from: current, to: defaultEdge.to, reason: "only path" }, logger);
|
|
760
|
+
return defaultEdge.to;
|
|
761
|
+
}
|
|
745
762
|
// Claude evaluates which condition matches. Include input so conditions
|
|
746
763
|
// can reference workflow-level flags like dryRun, and expose evals so
|
|
747
764
|
// routing edges can read `priorNode.evals.X.pass`.
|
|
@@ -756,7 +773,14 @@ async function resolveNext(workflow, current, results, input, claude, observer,
|
|
|
756
773
|
for (const [k, v] of results.entries()) {
|
|
757
774
|
const { view, missing } = buildRouteEvalEntry(v, workflow.nodes[k]);
|
|
758
775
|
context[k] = view;
|
|
759
|
-
|
|
776
|
+
// Only a successful node has an output contract to violate. A node that
|
|
777
|
+
// was skipped (requires not met) or failed before producing output never
|
|
778
|
+
// emitted its declared properties; its data is { skipped_reason } / { error }.
|
|
779
|
+
// Warning that those nodes are "missing declared properties" is misleading
|
|
780
|
+
// noise — it alarms operators and pollutes telemetry on every skip. Still
|
|
781
|
+
// build the view above so routing can read the skipped/failed data; only
|
|
782
|
+
// suppress the warning + node:warning for non-success nodes.
|
|
783
|
+
if (missing.length > 0 && v.status === "success") {
|
|
760
784
|
// Loud signal for the operator. The view itself already replaces the
|
|
761
785
|
// missing keys with explicit `null`, so the LLM evaluator cannot
|
|
762
786
|
// ghost-match "is N" or "is undefined" against a structurally-absent
|
package/dist/mcp-catalog.js
CHANGED
|
@@ -47,7 +47,10 @@ const gitlab = {
|
|
|
47
47
|
if (!creds.GITLAB_TOKEN)
|
|
48
48
|
return undefined;
|
|
49
49
|
const env = { GITLAB_PERSONAL_ACCESS_TOKEN: creds.GITLAB_TOKEN };
|
|
50
|
-
|
|
50
|
+
// Normalize trailing slash(es) so a pasted "https://gl.corp.com/" (or even
|
|
51
|
+
// the canonical "https://gitlab.com/") does not produce a double-slash
|
|
52
|
+
// "//api/v4". The /+$ also collapses accidental multi-trailing-slash input.
|
|
53
|
+
const baseUrl = (creds.GITLAB_URL || "https://gitlab.com").replace(/\/+$/, "");
|
|
51
54
|
if (baseUrl !== "https://gitlab.com")
|
|
52
55
|
env.GITLAB_API_URL = `${baseUrl}/api/v4`;
|
|
53
56
|
return {
|
package/dist/schema.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export declare const configFieldZ: z.ZodObject<{
|
|
|
17
17
|
description: z.ZodString;
|
|
18
18
|
required: z.ZodOptional<z.ZodBoolean>;
|
|
19
19
|
env: z.ZodOptional<z.ZodString>;
|
|
20
|
-
}, "
|
|
20
|
+
}, "strict", z.ZodTypeAny, {
|
|
21
21
|
description: string;
|
|
22
22
|
required?: boolean | undefined;
|
|
23
23
|
env?: string | undefined;
|
|
@@ -30,12 +30,14 @@ export declare const configFieldZ: z.ZodObject<{
|
|
|
30
30
|
* Zod schema for tool metadata (name, description, input_schema).
|
|
31
31
|
* Note: `handler` is intentionally omitted — Zod schemas validate
|
|
32
32
|
* serializable data (JSON import/export), not runtime function refs.
|
|
33
|
+
*
|
|
34
|
+
* .strict() to match the published Tool `$def`'s `additionalProperties: false`.
|
|
33
35
|
*/
|
|
34
36
|
export declare const toolZ: z.ZodObject<{
|
|
35
37
|
name: z.ZodString;
|
|
36
38
|
description: z.ZodString;
|
|
37
39
|
input_schema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
38
|
-
}, "
|
|
40
|
+
}, "strict", z.ZodTypeAny, {
|
|
39
41
|
description: string;
|
|
40
42
|
name: string;
|
|
41
43
|
input_schema: Record<string, unknown>;
|
|
@@ -179,7 +181,7 @@ export declare const skillZ: z.ZodEffects<z.ZodObject<{
|
|
|
179
181
|
description: z.ZodString;
|
|
180
182
|
required: z.ZodOptional<z.ZodBoolean>;
|
|
181
183
|
env: z.ZodOptional<z.ZodString>;
|
|
182
|
-
}, "
|
|
184
|
+
}, "strict", z.ZodTypeAny, {
|
|
183
185
|
description: string;
|
|
184
186
|
required?: boolean | undefined;
|
|
185
187
|
env?: string | undefined;
|
|
@@ -192,7 +194,7 @@ export declare const skillZ: z.ZodEffects<z.ZodObject<{
|
|
|
192
194
|
name: z.ZodString;
|
|
193
195
|
description: z.ZodString;
|
|
194
196
|
input_schema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
195
|
-
}, "
|
|
197
|
+
}, "strict", z.ZodTypeAny, {
|
|
196
198
|
description: string;
|
|
197
199
|
name: string;
|
|
198
200
|
input_schema: Record<string, unknown>;
|
|
@@ -2623,7 +2625,7 @@ export declare function parseWorkflow(raw: unknown): {
|
|
|
2623
2625
|
}> | undefined;
|
|
2624
2626
|
};
|
|
2625
2627
|
export interface WorkflowError {
|
|
2626
|
-
code: "MISSING_ENTRY" | "UNKNOWN_EDGE_SOURCE" | "UNKNOWN_EDGE_TARGET" | "UNREACHABLE_NODE" | "UNKNOWN_SKILL" | "SELF_LOOP" | "UNBOUNDED_CYCLE" | "UNSUPPORTED_EVAL_POLICY" | "INVALID_INLINE_SKILL";
|
|
2628
|
+
code: "MISSING_ENTRY" | "UNKNOWN_EDGE_SOURCE" | "UNKNOWN_EDGE_TARGET" | "UNREACHABLE_NODE" | "UNKNOWN_SKILL" | "SELF_LOOP" | "UNBOUNDED_CYCLE" | "AMBIGUOUS_EDGES" | "UNSUPPORTED_EVAL_POLICY" | "INVALID_INLINE_SKILL";
|
|
2627
2629
|
message: string;
|
|
2628
2630
|
nodeId?: string;
|
|
2629
2631
|
}
|
|
@@ -3402,6 +3404,11 @@ export declare const skillJsonSchema: {
|
|
|
3402
3404
|
readonly McpServerConfig: {
|
|
3403
3405
|
readonly type: "object";
|
|
3404
3406
|
readonly description: "External MCP server definition.";
|
|
3407
|
+
readonly anyOf: readonly [{
|
|
3408
|
+
readonly required: readonly ["command"];
|
|
3409
|
+
}, {
|
|
3410
|
+
readonly required: readonly ["url"];
|
|
3411
|
+
}];
|
|
3405
3412
|
readonly additionalProperties: false;
|
|
3406
3413
|
readonly properties: {
|
|
3407
3414
|
readonly type: {
|
package/dist/schema.js
CHANGED
|
@@ -14,21 +14,32 @@ export { sourceZ };
|
|
|
14
14
|
export { workflowInputsZ };
|
|
15
15
|
// ─── Zod Schemas ─────────────────────────────────────────────────
|
|
16
16
|
export const jsonSchemaZ = z.record(z.unknown());
|
|
17
|
-
|
|
17
|
+
// .strict() to match the published skill JSON Schema's ConfigField
|
|
18
|
+
// `additionalProperties: false`. Without it Zod silently STRIPPED an unknown
|
|
19
|
+
// nested key while ajv REJECTED it (the #214/#225 divergence class, missed for
|
|
20
|
+
// configFieldZ/toolZ). custom-loader.ts builds Skill objects from frontmatter
|
|
21
|
+
// and never runs these schemas, so tightening is safe downstream.
|
|
22
|
+
export const configFieldZ = z
|
|
23
|
+
.object({
|
|
18
24
|
description: z.string(),
|
|
19
25
|
required: z.boolean().optional(),
|
|
20
26
|
env: z.string().optional(),
|
|
21
|
-
})
|
|
27
|
+
})
|
|
28
|
+
.strict();
|
|
22
29
|
/**
|
|
23
30
|
* Zod schema for tool metadata (name, description, input_schema).
|
|
24
31
|
* Note: `handler` is intentionally omitted — Zod schemas validate
|
|
25
32
|
* serializable data (JSON import/export), not runtime function refs.
|
|
33
|
+
*
|
|
34
|
+
* .strict() to match the published Tool `$def`'s `additionalProperties: false`.
|
|
26
35
|
*/
|
|
27
|
-
export const toolZ = z
|
|
36
|
+
export const toolZ = z
|
|
37
|
+
.object({
|
|
28
38
|
name: z.string().min(1),
|
|
29
39
|
description: z.string(),
|
|
30
40
|
input_schema: jsonSchemaZ,
|
|
31
|
-
})
|
|
41
|
+
})
|
|
42
|
+
.strict();
|
|
32
43
|
export const skillCategoryZ = z.enum(SKILL_CATEGORIES);
|
|
33
44
|
export const mcpServerConfigZ = z
|
|
34
45
|
.object({
|
|
@@ -344,6 +355,32 @@ export function validateWorkflow(workflow, knownSkills) {
|
|
|
344
355
|
});
|
|
345
356
|
}
|
|
346
357
|
}
|
|
358
|
+
// Edge determinism: a node with two or more out-edges that have no `when`
|
|
359
|
+
// clause is ambiguous. The executor's resolveNext picks the first such edge
|
|
360
|
+
// and silently drops the rest, wasting a route eval on a deterministic hop
|
|
361
|
+
// and leaving the other targets unreachable. Reject it at load time so the
|
|
362
|
+
// author sees the problem instead of getting a silent first-edge-wins.
|
|
363
|
+
// Only count edges whose source is a real node (broken sources are already
|
|
364
|
+
// reported above as UNKNOWN_EDGE_SOURCE).
|
|
365
|
+
const unconditionalByNode = new Map();
|
|
366
|
+
for (const edge of workflow.edges) {
|
|
367
|
+
if (!nodeIds.has(edge.from))
|
|
368
|
+
continue;
|
|
369
|
+
if (edge.when)
|
|
370
|
+
continue;
|
|
371
|
+
const list = unconditionalByNode.get(edge.from) ?? [];
|
|
372
|
+
list.push(edge.to);
|
|
373
|
+
unconditionalByNode.set(edge.from, list);
|
|
374
|
+
}
|
|
375
|
+
for (const [from, targets] of unconditionalByNode) {
|
|
376
|
+
if (targets.length > 1) {
|
|
377
|
+
errors.push({
|
|
378
|
+
code: "AMBIGUOUS_EDGES",
|
|
379
|
+
message: `Node "${from}" has ${targets.length} unconditional out-edges (to ${targets.join(", ")}); add a 'when' clause to all but one so routing is deterministic`,
|
|
380
|
+
nodeId: from,
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
}
|
|
347
384
|
// Don't check reachability if there are structural errors
|
|
348
385
|
if (errors.length > 0)
|
|
349
386
|
return errors;
|
|
@@ -1009,6 +1046,11 @@ export const skillJsonSchema = {
|
|
|
1009
1046
|
McpServerConfig: {
|
|
1010
1047
|
type: "object",
|
|
1011
1048
|
description: "External MCP server definition.",
|
|
1049
|
+
// An MCP server must declare command (stdio) or url (http), mirroring
|
|
1050
|
+
// mcpServerConfigZ.refine(c => c.command || c.url) and the workflow
|
|
1051
|
+
// inline-skill mcp block. Without this the published skill.json accepted a
|
|
1052
|
+
// transport-less mcp block the runtime parser rejects (Zod<->ajv drift).
|
|
1053
|
+
anyOf: [{ required: ["command"] }, { required: ["url"] }],
|
|
1012
1054
|
additionalProperties: false,
|
|
1013
1055
|
properties: {
|
|
1014
1056
|
type: {
|
|
@@ -7,6 +7,13 @@
|
|
|
7
7
|
* or `node:crypto` into bundlers that target the browser.
|
|
8
8
|
*/
|
|
9
9
|
import type { ResolvedSource, Source, SourceResolutionContext, SourceResolutionMap } from "./sources.js";
|
|
10
|
+
/**
|
|
11
|
+
* Error-message prefix used when a `url:` source cannot be fetched in
|
|
12
|
+
* `--offline` mode. Exported so callers that intentionally degrade to a default
|
|
13
|
+
* on this one failure (e.g. `templates.ts`) can detect it without coupling to
|
|
14
|
+
* the full message text.
|
|
15
|
+
*/
|
|
16
|
+
export declare const SOURCE_OFFLINE_REQUIRES_FETCH = "SOURCE_OFFLINE_REQUIRES_FETCH";
|
|
10
17
|
/**
|
|
11
18
|
* Produce a stable 16-hex-char hash of `content` for use as a cache key /
|
|
12
19
|
* change-detection ID.
|
package/dist/source-resolver.js
CHANGED
|
@@ -12,6 +12,13 @@ import * as path from "node:path";
|
|
|
12
12
|
import { normalizeSource } from "./sources.js";
|
|
13
13
|
/** Schemes a `url:` source is allowed to use. Everything else is rejected. */
|
|
14
14
|
const ALLOWED_URL_SCHEMES = new Set(["http:", "https:"]);
|
|
15
|
+
/**
|
|
16
|
+
* Error-message prefix used when a `url:` source cannot be fetched in
|
|
17
|
+
* `--offline` mode. Exported so callers that intentionally degrade to a default
|
|
18
|
+
* on this one failure (e.g. `templates.ts`) can detect it without coupling to
|
|
19
|
+
* the full message text.
|
|
20
|
+
*/
|
|
21
|
+
export const SOURCE_OFFLINE_REQUIRES_FETCH = "SOURCE_OFFLINE_REQUIRES_FETCH";
|
|
15
22
|
/** Default DNS resolver used when the context does not inject one. */
|
|
16
23
|
const defaultDnsLookup = async (hostname) => {
|
|
17
24
|
const records = await dns.lookup(hostname, { all: true });
|
|
@@ -80,7 +87,7 @@ export async function resolveSource(source, fieldPath, ctx) {
|
|
|
80
87
|
}
|
|
81
88
|
if (kind === "url") {
|
|
82
89
|
if (ctx.offline) {
|
|
83
|
-
throw new Error(
|
|
90
|
+
throw new Error(`${SOURCE_OFFLINE_REQUIRES_FETCH}: cannot fetch ${value} in --offline mode (referenced by ${fieldPath}).`);
|
|
84
91
|
}
|
|
85
92
|
// Validate type field on tagged URL forms — v1 only accepts "fetch" (the default).
|
|
86
93
|
if (typeof source === "object" && "url" in source && source.type && source.type !== "fetch") {
|
package/dist/templates.d.ts
CHANGED
|
@@ -34,7 +34,12 @@ export interface SourceLoadOptions {
|
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
36
36
|
* Load a template from a file path or URL.
|
|
37
|
-
*
|
|
37
|
+
*
|
|
38
|
+
* Returns the default only when the source is empty/unset, or when a URL source
|
|
39
|
+
* is intentionally skipped under `--offline`. A CONFIGURED source that fails to
|
|
40
|
+
* resolve (404, 403, SSRF block, read error) now THROWS instead of silently
|
|
41
|
+
* degrading to the built-in default — a typo'd or unauthorized template URL is
|
|
42
|
+
* a misconfiguration, not a no-op. This matches the executor's Source handling.
|
|
38
43
|
*
|
|
39
44
|
* Accepts the legacy `cwd?: string` signature for backward compat.
|
|
40
45
|
*/
|
|
@@ -52,6 +57,9 @@ export declare function resolveTemplates(config: {
|
|
|
52
57
|
* Returns { resolved, urls } — resolved text for all sources; urls is kept
|
|
53
58
|
* for API compat but will be empty since URLs now resolve eagerly.
|
|
54
59
|
*
|
|
60
|
+
* A configured source that fails to resolve THROWS (matching the executor and
|
|
61
|
+
* `loadTemplate`); only the intentional `--offline` URL skip is swallowed.
|
|
62
|
+
*
|
|
55
63
|
* Accepts the legacy `cwd?: string` signature for backward compat.
|
|
56
64
|
*/
|
|
57
65
|
export declare function loadAdditionalContext(sources: string[], options?: SourceLoadOptions | string): Promise<{
|
package/dist/templates.js
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import * as path from "node:path";
|
|
15
15
|
import { classifySource } from "./sources.js";
|
|
16
|
-
import { resolveSource } from "./source-resolver.js";
|
|
16
|
+
import { resolveSource, SOURCE_OFFLINE_REQUIRES_FETCH } from "./source-resolver.js";
|
|
17
17
|
import { consoleLogger } from "./types.js";
|
|
18
18
|
export const DEFAULT_ISSUE_TEMPLATE = `## Summary
|
|
19
19
|
<!-- One-line description of the issue -->
|
|
@@ -61,9 +61,26 @@ function buildCtx(options) {
|
|
|
61
61
|
logger: consoleLogger,
|
|
62
62
|
};
|
|
63
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* True when a resolution error is the intentional `--offline` skip of a URL
|
|
66
|
+
* source. Offline mode is the one failure we deliberately swallow into the
|
|
67
|
+
* fallback: the operator explicitly asked to skip URL Sources. Every other
|
|
68
|
+
* failure (404/403/SSRF block/read error/unreachable) is a real
|
|
69
|
+
* misconfiguration and must surface, matching the executor's per-node Source
|
|
70
|
+
* resolution which hard-throws on all of these.
|
|
71
|
+
*/
|
|
72
|
+
function isOfflineSkip(err) {
|
|
73
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
74
|
+
return msg.startsWith(SOURCE_OFFLINE_REQUIRES_FETCH);
|
|
75
|
+
}
|
|
64
76
|
/**
|
|
65
77
|
* Load a template from a file path or URL.
|
|
66
|
-
*
|
|
78
|
+
*
|
|
79
|
+
* Returns the default only when the source is empty/unset, or when a URL source
|
|
80
|
+
* is intentionally skipped under `--offline`. A CONFIGURED source that fails to
|
|
81
|
+
* resolve (404, 403, SSRF block, read error) now THROWS instead of silently
|
|
82
|
+
* degrading to the built-in default — a typo'd or unauthorized template URL is
|
|
83
|
+
* a misconfiguration, not a no-op. This matches the executor's Source handling.
|
|
67
84
|
*
|
|
68
85
|
* Accepts the legacy `cwd?: string` signature for backward compat.
|
|
69
86
|
*/
|
|
@@ -76,9 +93,12 @@ export async function loadTemplate(source, fallback, options = {}) {
|
|
|
76
93
|
return resolved.content;
|
|
77
94
|
}
|
|
78
95
|
catch (err) {
|
|
96
|
+
if (isOfflineSkip(err)) {
|
|
97
|
+
console.warn(`[templates] Skipping URL template in --offline mode, using default.`);
|
|
98
|
+
return fallback;
|
|
99
|
+
}
|
|
79
100
|
const msg = err instanceof Error ? err.message : String(err);
|
|
80
|
-
|
|
81
|
-
return fallback;
|
|
101
|
+
throw new Error(`Failed to load configured template "${source.trim()}": ${msg}`);
|
|
82
102
|
}
|
|
83
103
|
}
|
|
84
104
|
/**
|
|
@@ -98,6 +118,9 @@ export async function resolveTemplates(config, options = {}) {
|
|
|
98
118
|
* Returns { resolved, urls } — resolved text for all sources; urls is kept
|
|
99
119
|
* for API compat but will be empty since URLs now resolve eagerly.
|
|
100
120
|
*
|
|
121
|
+
* A configured source that fails to resolve THROWS (matching the executor and
|
|
122
|
+
* `loadTemplate`); only the intentional `--offline` URL skip is swallowed.
|
|
123
|
+
*
|
|
101
124
|
* Accepts the legacy `cwd?: string` signature for backward compat.
|
|
102
125
|
*/
|
|
103
126
|
export async function loadAdditionalContext(sources, options = {}) {
|
|
@@ -123,8 +146,15 @@ export async function loadAdditionalContext(sources, options = {}) {
|
|
|
123
146
|
}
|
|
124
147
|
}
|
|
125
148
|
catch (err) {
|
|
149
|
+
// Offline skip of a URL source is intentional; everything else (404,
|
|
150
|
+
// 403, SSRF block, read error) is a misconfiguration and must surface
|
|
151
|
+
// rather than silently dropping the configured context document.
|
|
152
|
+
if (isOfflineSkip(err)) {
|
|
153
|
+
console.warn(`[templates] Skipping URL context source "${trimmed}" in --offline mode.`);
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
126
156
|
const msg = err instanceof Error ? err.message : String(err);
|
|
127
|
-
|
|
157
|
+
throw new Error(`Failed to load configured context source "${trimmed}": ${msg}`);
|
|
128
158
|
}
|
|
129
159
|
}
|
|
130
160
|
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sweny-ai/core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.108",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"sweny": "./dist/cli/main.js"
|
|
7
7
|
},
|
|
8
8
|
"description": "Skill library, DAG workflow orchestration, and E2E browser testing powered by Claude",
|
|
9
9
|
"license": "MIT",
|
|
10
|
+
"engines": {
|
|
11
|
+
"node": ">=20"
|
|
12
|
+
},
|
|
10
13
|
"exports": {
|
|
11
14
|
".": "./dist/index.js",
|
|
12
15
|
"./browser": "./dist/browser.js",
|
|
@@ -15,7 +18,8 @@
|
|
|
15
18
|
"./workflows": "./dist/workflows/index.js",
|
|
16
19
|
"./testing": "./dist/testing.js",
|
|
17
20
|
"./schema": "./dist/schema.js",
|
|
18
|
-
"./new": "./dist/cli/new.js"
|
|
21
|
+
"./new": "./dist/cli/new.js",
|
|
22
|
+
"./package.json": "./package.json"
|
|
19
23
|
},
|
|
20
24
|
"typesVersions": {
|
|
21
25
|
"*": {
|