@holdpoint/yaml-core 0.1.0-alpha.1 → 0.1.0-alpha.11
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/index.d.ts +75 -232
- package/dist/index.js +38 -9
- package/dist/index.js.map +1 -1
- package/dist/runner-entry.d.ts +6 -5
- package/dist/runner-entry.js +3 -2
- package/dist/runner-entry.js.map +1 -1
- package/package.json +7 -8
package/dist/index.d.ts
CHANGED
|
@@ -24,264 +24,107 @@ declare function generateYaml(config: HoldpointConfig): string;
|
|
|
24
24
|
*/
|
|
25
25
|
declare function matchesWhen(when: string | undefined, changedFiles: string[], userPatterns?: Record<string, string>): boolean;
|
|
26
26
|
|
|
27
|
-
declare const HookEventSchema: z.ZodEnum<
|
|
27
|
+
declare const HookEventSchema: z.ZodEnum<{
|
|
28
|
+
session_start: "session_start";
|
|
29
|
+
message_submit: "message_submit";
|
|
30
|
+
before_tool: "before_tool";
|
|
31
|
+
after_tool: "after_tool";
|
|
32
|
+
session_end: "session_end";
|
|
33
|
+
before_done: "before_done";
|
|
34
|
+
}>;
|
|
35
|
+
declare const InjectSpecSchema: z.ZodObject<{
|
|
36
|
+
text: z.ZodOptional<z.ZodString>;
|
|
37
|
+
files: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
38
|
+
datetime: z.ZodOptional<z.ZodBoolean>;
|
|
39
|
+
}, z.core.$strip>;
|
|
28
40
|
declare const ConditionDefSchema: z.ZodObject<{
|
|
29
41
|
id: z.ZodString;
|
|
30
|
-
operator: z.ZodEnum<
|
|
42
|
+
operator: z.ZodEnum<{
|
|
43
|
+
file_exists: "file_exists";
|
|
44
|
+
file_contains: "file_contains";
|
|
45
|
+
env_var_set: "env_var_set";
|
|
46
|
+
shell_returns_0: "shell_returns_0";
|
|
47
|
+
}>;
|
|
31
48
|
path: z.ZodOptional<z.ZodString>;
|
|
32
49
|
contains: z.ZodOptional<z.ZodString>;
|
|
33
50
|
envVar: z.ZodOptional<z.ZodString>;
|
|
34
51
|
cmd: z.ZodOptional<z.ZodString>;
|
|
35
|
-
},
|
|
36
|
-
|
|
37
|
-
operator: "file_exists" | "file_contains" | "env_var_set" | "shell_returns_0";
|
|
38
|
-
path?: string | undefined;
|
|
39
|
-
contains?: string | undefined;
|
|
40
|
-
envVar?: string | undefined;
|
|
41
|
-
cmd?: string | undefined;
|
|
42
|
-
}, {
|
|
43
|
-
id: string;
|
|
44
|
-
operator: "file_exists" | "file_contains" | "env_var_set" | "shell_returns_0";
|
|
45
|
-
path?: string | undefined;
|
|
46
|
-
contains?: string | undefined;
|
|
47
|
-
envVar?: string | undefined;
|
|
48
|
-
cmd?: string | undefined;
|
|
49
|
-
}>;
|
|
50
|
-
declare const CheckDefSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
|
|
52
|
+
}, z.core.$strip>;
|
|
53
|
+
declare const CheckDefSchema: z.ZodPreprocess<z.ZodObject<{
|
|
51
54
|
id: z.ZodString;
|
|
52
55
|
label: z.ZodString;
|
|
53
|
-
on: z.ZodOptional<z.ZodEnum<
|
|
56
|
+
on: z.ZodOptional<z.ZodEnum<{
|
|
57
|
+
session_start: "session_start";
|
|
58
|
+
message_submit: "message_submit";
|
|
59
|
+
before_tool: "before_tool";
|
|
60
|
+
after_tool: "after_tool";
|
|
61
|
+
session_end: "session_end";
|
|
62
|
+
before_done: "before_done";
|
|
63
|
+
}>>;
|
|
54
64
|
when: z.ZodOptional<z.ZodString>;
|
|
55
65
|
cmd: z.ZodOptional<z.ZodString>;
|
|
56
66
|
prompt: z.ZodOptional<z.ZodString>;
|
|
67
|
+
inject: z.ZodOptional<z.ZodObject<{
|
|
68
|
+
text: z.ZodOptional<z.ZodString>;
|
|
69
|
+
files: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
70
|
+
datetime: z.ZodOptional<z.ZodBoolean>;
|
|
71
|
+
}, z.core.$strip>>;
|
|
57
72
|
conditionId: z.ZodOptional<z.ZodString>;
|
|
58
|
-
},
|
|
59
|
-
|
|
60
|
-
label: string;
|
|
61
|
-
cmd?: string | undefined;
|
|
62
|
-
on?: "before_done" | undefined;
|
|
63
|
-
when?: string | undefined;
|
|
64
|
-
prompt?: string | undefined;
|
|
65
|
-
conditionId?: string | undefined;
|
|
66
|
-
}, {
|
|
67
|
-
id: string;
|
|
68
|
-
label: string;
|
|
69
|
-
cmd?: string | undefined;
|
|
70
|
-
on?: "before_done" | undefined;
|
|
71
|
-
when?: string | undefined;
|
|
72
|
-
prompt?: string | undefined;
|
|
73
|
-
conditionId?: string | undefined;
|
|
74
|
-
}>, {
|
|
75
|
-
id: string;
|
|
76
|
-
label: string;
|
|
77
|
-
cmd?: string | undefined;
|
|
78
|
-
on?: "before_done" | undefined;
|
|
79
|
-
when?: string | undefined;
|
|
80
|
-
prompt?: string | undefined;
|
|
81
|
-
conditionId?: string | undefined;
|
|
82
|
-
}, {
|
|
83
|
-
id: string;
|
|
84
|
-
label: string;
|
|
85
|
-
cmd?: string | undefined;
|
|
86
|
-
on?: "before_done" | undefined;
|
|
87
|
-
when?: string | undefined;
|
|
88
|
-
prompt?: string | undefined;
|
|
89
|
-
conditionId?: string | undefined;
|
|
90
|
-
}>, {
|
|
91
|
-
id: string;
|
|
92
|
-
label: string;
|
|
93
|
-
cmd?: string | undefined;
|
|
94
|
-
on?: "before_done" | undefined;
|
|
95
|
-
when?: string | undefined;
|
|
96
|
-
prompt?: string | undefined;
|
|
97
|
-
conditionId?: string | undefined;
|
|
98
|
-
}, unknown>;
|
|
99
|
-
declare const HoldpointConfigSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
|
|
73
|
+
}, z.core.$strip>>;
|
|
74
|
+
declare const HoldpointConfigSchema: z.ZodPreprocess<z.ZodObject<{
|
|
100
75
|
version: z.ZodDefault<z.ZodNumber>;
|
|
101
76
|
context: z.ZodDefault<z.ZodObject<{
|
|
102
77
|
guides: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
103
|
-
},
|
|
104
|
-
guides: Record<string, string>;
|
|
105
|
-
}, {
|
|
106
|
-
guides?: Record<string, string> | undefined;
|
|
107
|
-
}>>;
|
|
78
|
+
}, z.core.$strip>>;
|
|
108
79
|
conditions: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
109
80
|
id: z.ZodString;
|
|
110
|
-
operator: z.ZodEnum<
|
|
81
|
+
operator: z.ZodEnum<{
|
|
82
|
+
file_exists: "file_exists";
|
|
83
|
+
file_contains: "file_contains";
|
|
84
|
+
env_var_set: "env_var_set";
|
|
85
|
+
shell_returns_0: "shell_returns_0";
|
|
86
|
+
}>;
|
|
111
87
|
path: z.ZodOptional<z.ZodString>;
|
|
112
88
|
contains: z.ZodOptional<z.ZodString>;
|
|
113
89
|
envVar: z.ZodOptional<z.ZodString>;
|
|
114
90
|
cmd: z.ZodOptional<z.ZodString>;
|
|
115
|
-
},
|
|
116
|
-
|
|
117
|
-
operator: "file_exists" | "file_contains" | "env_var_set" | "shell_returns_0";
|
|
118
|
-
path?: string | undefined;
|
|
119
|
-
contains?: string | undefined;
|
|
120
|
-
envVar?: string | undefined;
|
|
121
|
-
cmd?: string | undefined;
|
|
122
|
-
}, {
|
|
123
|
-
id: string;
|
|
124
|
-
operator: "file_exists" | "file_contains" | "env_var_set" | "shell_returns_0";
|
|
125
|
-
path?: string | undefined;
|
|
126
|
-
contains?: string | undefined;
|
|
127
|
-
envVar?: string | undefined;
|
|
128
|
-
cmd?: string | undefined;
|
|
129
|
-
}>, "many">>;
|
|
130
|
-
checks: z.ZodDefault<z.ZodArray<z.ZodEffects<z.ZodEffects<z.ZodObject<{
|
|
91
|
+
}, z.core.$strip>>>;
|
|
92
|
+
checks: z.ZodDefault<z.ZodArray<z.ZodPreprocess<z.ZodObject<{
|
|
131
93
|
id: z.ZodString;
|
|
132
94
|
label: z.ZodString;
|
|
133
|
-
on: z.ZodOptional<z.ZodEnum<
|
|
95
|
+
on: z.ZodOptional<z.ZodEnum<{
|
|
96
|
+
session_start: "session_start";
|
|
97
|
+
message_submit: "message_submit";
|
|
98
|
+
before_tool: "before_tool";
|
|
99
|
+
after_tool: "after_tool";
|
|
100
|
+
session_end: "session_end";
|
|
101
|
+
before_done: "before_done";
|
|
102
|
+
}>>;
|
|
134
103
|
when: z.ZodOptional<z.ZodString>;
|
|
135
104
|
cmd: z.ZodOptional<z.ZodString>;
|
|
136
105
|
prompt: z.ZodOptional<z.ZodString>;
|
|
106
|
+
inject: z.ZodOptional<z.ZodObject<{
|
|
107
|
+
text: z.ZodOptional<z.ZodString>;
|
|
108
|
+
files: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
109
|
+
datetime: z.ZodOptional<z.ZodBoolean>;
|
|
110
|
+
}, z.core.$strip>>;
|
|
137
111
|
conditionId: z.ZodOptional<z.ZodString>;
|
|
138
|
-
},
|
|
139
|
-
id: string;
|
|
140
|
-
label: string;
|
|
141
|
-
cmd?: string | undefined;
|
|
142
|
-
on?: "before_done" | undefined;
|
|
143
|
-
when?: string | undefined;
|
|
144
|
-
prompt?: string | undefined;
|
|
145
|
-
conditionId?: string | undefined;
|
|
146
|
-
}, {
|
|
147
|
-
id: string;
|
|
148
|
-
label: string;
|
|
149
|
-
cmd?: string | undefined;
|
|
150
|
-
on?: "before_done" | undefined;
|
|
151
|
-
when?: string | undefined;
|
|
152
|
-
prompt?: string | undefined;
|
|
153
|
-
conditionId?: string | undefined;
|
|
154
|
-
}>, {
|
|
155
|
-
id: string;
|
|
156
|
-
label: string;
|
|
157
|
-
cmd?: string | undefined;
|
|
158
|
-
on?: "before_done" | undefined;
|
|
159
|
-
when?: string | undefined;
|
|
160
|
-
prompt?: string | undefined;
|
|
161
|
-
conditionId?: string | undefined;
|
|
162
|
-
}, {
|
|
163
|
-
id: string;
|
|
164
|
-
label: string;
|
|
165
|
-
cmd?: string | undefined;
|
|
166
|
-
on?: "before_done" | undefined;
|
|
167
|
-
when?: string | undefined;
|
|
168
|
-
prompt?: string | undefined;
|
|
169
|
-
conditionId?: string | undefined;
|
|
170
|
-
}>, {
|
|
171
|
-
id: string;
|
|
172
|
-
label: string;
|
|
173
|
-
cmd?: string | undefined;
|
|
174
|
-
on?: "before_done" | undefined;
|
|
175
|
-
when?: string | undefined;
|
|
176
|
-
prompt?: string | undefined;
|
|
177
|
-
conditionId?: string | undefined;
|
|
178
|
-
}, unknown>, "many">>;
|
|
112
|
+
}, z.core.$strip>>>>;
|
|
179
113
|
patterns: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
180
|
-
session_context_files: z.ZodOptional<z.ZodArray<z.ZodString
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
conditions: {
|
|
196
|
-
id: string;
|
|
197
|
-
operator: "file_exists" | "file_contains" | "env_var_set" | "shell_returns_0";
|
|
198
|
-
path?: string | undefined;
|
|
199
|
-
contains?: string | undefined;
|
|
200
|
-
envVar?: string | undefined;
|
|
201
|
-
cmd?: string | undefined;
|
|
202
|
-
}[];
|
|
203
|
-
patterns?: Record<string, string> | undefined;
|
|
204
|
-
session_context_files?: string[] | undefined;
|
|
205
|
-
}, {
|
|
206
|
-
checks?: unknown[] | undefined;
|
|
207
|
-
version?: number | undefined;
|
|
208
|
-
context?: {
|
|
209
|
-
guides?: Record<string, string> | undefined;
|
|
210
|
-
} | undefined;
|
|
211
|
-
conditions?: {
|
|
212
|
-
id: string;
|
|
213
|
-
operator: "file_exists" | "file_contains" | "env_var_set" | "shell_returns_0";
|
|
214
|
-
path?: string | undefined;
|
|
215
|
-
contains?: string | undefined;
|
|
216
|
-
envVar?: string | undefined;
|
|
217
|
-
cmd?: string | undefined;
|
|
218
|
-
}[] | undefined;
|
|
219
|
-
patterns?: Record<string, string> | undefined;
|
|
220
|
-
session_context_files?: string[] | undefined;
|
|
221
|
-
}>, {
|
|
222
|
-
checks: {
|
|
223
|
-
id: string;
|
|
224
|
-
label: string;
|
|
225
|
-
cmd?: string | undefined;
|
|
226
|
-
on?: "before_done" | undefined;
|
|
227
|
-
when?: string | undefined;
|
|
228
|
-
prompt?: string | undefined;
|
|
229
|
-
conditionId?: string | undefined;
|
|
230
|
-
}[];
|
|
231
|
-
version: number;
|
|
232
|
-
context: {
|
|
233
|
-
guides: Record<string, string>;
|
|
234
|
-
};
|
|
235
|
-
conditions: {
|
|
236
|
-
id: string;
|
|
237
|
-
operator: "file_exists" | "file_contains" | "env_var_set" | "shell_returns_0";
|
|
238
|
-
path?: string | undefined;
|
|
239
|
-
contains?: string | undefined;
|
|
240
|
-
envVar?: string | undefined;
|
|
241
|
-
cmd?: string | undefined;
|
|
242
|
-
}[];
|
|
243
|
-
patterns?: Record<string, string> | undefined;
|
|
244
|
-
session_context_files?: string[] | undefined;
|
|
245
|
-
}, {
|
|
246
|
-
checks?: unknown[] | undefined;
|
|
247
|
-
version?: number | undefined;
|
|
248
|
-
context?: {
|
|
249
|
-
guides?: Record<string, string> | undefined;
|
|
250
|
-
} | undefined;
|
|
251
|
-
conditions?: {
|
|
252
|
-
id: string;
|
|
253
|
-
operator: "file_exists" | "file_contains" | "env_var_set" | "shell_returns_0";
|
|
254
|
-
path?: string | undefined;
|
|
255
|
-
contains?: string | undefined;
|
|
256
|
-
envVar?: string | undefined;
|
|
257
|
-
cmd?: string | undefined;
|
|
258
|
-
}[] | undefined;
|
|
259
|
-
patterns?: Record<string, string> | undefined;
|
|
260
|
-
session_context_files?: string[] | undefined;
|
|
261
|
-
}>, {
|
|
262
|
-
checks: {
|
|
263
|
-
id: string;
|
|
264
|
-
label: string;
|
|
265
|
-
cmd?: string | undefined;
|
|
266
|
-
on?: "before_done" | undefined;
|
|
267
|
-
when?: string | undefined;
|
|
268
|
-
prompt?: string | undefined;
|
|
269
|
-
conditionId?: string | undefined;
|
|
270
|
-
}[];
|
|
271
|
-
version: number;
|
|
272
|
-
context: {
|
|
273
|
-
guides: Record<string, string>;
|
|
274
|
-
};
|
|
275
|
-
conditions: {
|
|
276
|
-
id: string;
|
|
277
|
-
operator: "file_exists" | "file_contains" | "env_var_set" | "shell_returns_0";
|
|
278
|
-
path?: string | undefined;
|
|
279
|
-
contains?: string | undefined;
|
|
280
|
-
envVar?: string | undefined;
|
|
281
|
-
cmd?: string | undefined;
|
|
282
|
-
}[];
|
|
283
|
-
patterns?: Record<string, string> | undefined;
|
|
284
|
-
session_context_files?: string[] | undefined;
|
|
285
|
-
}, unknown>;
|
|
114
|
+
session_context_files: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
115
|
+
inject_datetime: z.ZodOptional<z.ZodBoolean>;
|
|
116
|
+
engines: z.ZodOptional<z.ZodObject<{
|
|
117
|
+
claude: z.ZodOptional<z.ZodObject<{
|
|
118
|
+
stop_command: z.ZodOptional<z.ZodString>;
|
|
119
|
+
live_command: z.ZodOptional<z.ZodString>;
|
|
120
|
+
}, z.core.$strip>>;
|
|
121
|
+
codex: z.ZodOptional<z.ZodObject<{
|
|
122
|
+
stop_command: z.ZodOptional<z.ZodString>;
|
|
123
|
+
}, z.core.$strip>>;
|
|
124
|
+
copilot: z.ZodOptional<z.ZodObject<{
|
|
125
|
+
check_command: z.ZodOptional<z.ZodString>;
|
|
126
|
+
}, z.core.$strip>>;
|
|
127
|
+
}, z.core.$strip>>;
|
|
128
|
+
}, z.core.$strip>>;
|
|
286
129
|
|
|
287
|
-
export { CheckDefSchema, ConditionDefSchema, HoldpointConfigSchema, HookEventSchema, generateYaml, matchesWhen, parseHoldpointYaml, validateConfig };
|
|
130
|
+
export { CheckDefSchema, ConditionDefSchema, HoldpointConfigSchema, HookEventSchema, InjectSpecSchema, generateYaml, matchesWhen, parseHoldpointYaml, validateConfig };
|
package/dist/index.js
CHANGED
|
@@ -7,7 +7,21 @@ import * as yaml from "js-yaml";
|
|
|
7
7
|
|
|
8
8
|
// src/schema.ts
|
|
9
9
|
import { z } from "zod";
|
|
10
|
-
var HookEventSchema = z.enum([
|
|
10
|
+
var HookEventSchema = z.enum([
|
|
11
|
+
"session_start",
|
|
12
|
+
"message_submit",
|
|
13
|
+
"before_tool",
|
|
14
|
+
"after_tool",
|
|
15
|
+
"session_end",
|
|
16
|
+
"before_done"
|
|
17
|
+
]);
|
|
18
|
+
var InjectSpecSchema = z.object({
|
|
19
|
+
text: z.string().optional(),
|
|
20
|
+
files: z.array(z.string()).optional(),
|
|
21
|
+
datetime: z.boolean().optional()
|
|
22
|
+
}).refine((i) => i.text !== void 0 || (i.files?.length ?? 0) > 0 || i.datetime === true, {
|
|
23
|
+
message: "inject must set at least one of text, files, or datetime"
|
|
24
|
+
});
|
|
11
25
|
var ConditionOperatorSchema = z.enum([
|
|
12
26
|
"file_exists",
|
|
13
27
|
"file_contains",
|
|
@@ -70,13 +84,17 @@ var CheckDefSchema = z.preprocess(
|
|
|
70
84
|
when: z.string().optional(),
|
|
71
85
|
cmd: z.string().optional(),
|
|
72
86
|
prompt: z.string().optional(),
|
|
87
|
+
inject: InjectSpecSchema.optional(),
|
|
73
88
|
conditionId: z.string().optional()
|
|
74
|
-
}).refine(
|
|
75
|
-
|
|
76
|
-
|
|
89
|
+
}).refine(
|
|
90
|
+
(c) => [c.cmd !== void 0, c.prompt !== void 0, c.inject !== void 0].filter(Boolean).length === 1,
|
|
91
|
+
{
|
|
92
|
+
message: "A check must have exactly one of cmd (command), prompt (agent instruction), or inject (context)"
|
|
93
|
+
}
|
|
94
|
+
)
|
|
77
95
|
);
|
|
78
96
|
var HoldpointContextSchema = z.object({
|
|
79
|
-
guides: z.record(z.string()).default({})
|
|
97
|
+
guides: z.record(z.string(), z.string()).default({})
|
|
80
98
|
});
|
|
81
99
|
var BUILTIN_SCOPES = /* @__PURE__ */ new Set([
|
|
82
100
|
"frontend",
|
|
@@ -96,6 +114,14 @@ var BUILTIN_SCOPES = /* @__PURE__ */ new Set([
|
|
|
96
114
|
"docs",
|
|
97
115
|
"structural"
|
|
98
116
|
]);
|
|
117
|
+
var EnginesConfigSchema = z.object({
|
|
118
|
+
claude: z.object({
|
|
119
|
+
stop_command: z.string().optional(),
|
|
120
|
+
live_command: z.string().optional()
|
|
121
|
+
}).optional(),
|
|
122
|
+
codex: z.object({ stop_command: z.string().optional() }).optional(),
|
|
123
|
+
copilot: z.object({ check_command: z.string().optional() }).optional()
|
|
124
|
+
}).optional();
|
|
99
125
|
var HoldpointConfigSchema = z.preprocess(
|
|
100
126
|
migrateLegacyConfig,
|
|
101
127
|
z.object({
|
|
@@ -103,8 +129,10 @@ var HoldpointConfigSchema = z.preprocess(
|
|
|
103
129
|
context: HoldpointContextSchema.default({ guides: {} }),
|
|
104
130
|
conditions: z.array(ConditionDefSchema).default([]),
|
|
105
131
|
checks: z.array(CheckDefSchema).default([]),
|
|
106
|
-
patterns: z.record(z.string()).optional(),
|
|
107
|
-
session_context_files: z.array(z.string()).optional()
|
|
132
|
+
patterns: z.record(z.string(), z.string()).optional(),
|
|
133
|
+
session_context_files: z.array(z.string()).optional(),
|
|
134
|
+
inject_datetime: z.boolean().optional(),
|
|
135
|
+
engines: EnginesConfigSchema
|
|
108
136
|
}).superRefine((data, ctx) => {
|
|
109
137
|
if (!data.patterns) return;
|
|
110
138
|
for (const [key, value] of Object.entries(data.patterns)) {
|
|
@@ -133,7 +161,7 @@ function parseHoldpointYaml(text) {
|
|
|
133
161
|
const raw = yaml.load(text);
|
|
134
162
|
const result = HoldpointConfigSchema.safeParse(raw);
|
|
135
163
|
if (!result.success) {
|
|
136
|
-
const messages = result.error.
|
|
164
|
+
const messages = result.error.issues.map((e) => `${e.path.join(".")}: ${e.message}`).join("\n");
|
|
137
165
|
throw new Error(`Invalid checks.yaml:
|
|
138
166
|
${messages}`);
|
|
139
167
|
}
|
|
@@ -146,7 +174,7 @@ function validateConfig(config) {
|
|
|
146
174
|
}
|
|
147
175
|
return {
|
|
148
176
|
valid: false,
|
|
149
|
-
errors: result.error.
|
|
177
|
+
errors: result.error.issues.map((e) => ({
|
|
150
178
|
path: e.path.join("."),
|
|
151
179
|
message: e.message
|
|
152
180
|
}))
|
|
@@ -166,6 +194,7 @@ export {
|
|
|
166
194
|
ConditionDefSchema,
|
|
167
195
|
HoldpointConfigSchema,
|
|
168
196
|
HookEventSchema,
|
|
197
|
+
InjectSpecSchema,
|
|
169
198
|
generateYaml,
|
|
170
199
|
matchesWhen,
|
|
171
200
|
parseHoldpointYaml,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/parser.ts","../src/schema.ts"],"sourcesContent":["import * as yaml from \"js-yaml\";\nimport type { HoldpointConfig, ValidationResult } from \"@holdpoint/types\";\nimport { HoldpointConfigSchema } from \"./schema.js\";\n\n/**\n * Parse a checks.yaml text into a HoldpointConfig.\n * Throws on invalid YAML or schema violations.\n */\nexport function parseHoldpointYaml(text: string): HoldpointConfig {\n const raw = yaml.load(text);\n const result = HoldpointConfigSchema.safeParse(raw);\n if (!result.success) {\n const messages = result.error.errors.map((e) => `${e.path.join(\".\")}: ${e.message}`).join(\"\\n\");\n throw new Error(`Invalid checks.yaml:\\n${messages}`);\n }\n return result.data as HoldpointConfig;\n}\n\n/**\n * Validate a parsed HoldpointConfig, returning structured errors.\n */\nexport function validateConfig(config: HoldpointConfig): ValidationResult {\n const result = HoldpointConfigSchema.safeParse(config);\n if (result.success) {\n return { valid: true, errors: [] };\n }\n return {\n valid: false,\n errors: result.error.errors.map((e) => ({\n path: e.path.join(\".\"),\n message: e.message,\n })),\n };\n}\n\n/**\n * Serialize a HoldpointConfig back to YAML text.\n */\nexport function generateYaml(config: HoldpointConfig): string {\n return yaml.dump(config, {\n indent: 2,\n lineWidth: 120,\n quotingType: '\"',\n forceQuotes: false,\n noRefs: true,\n });\n}\n","import { z } from \"zod\";\n\n// ─── Zod schemas ─────────────────────────────────────────────────────────────\n\nexport const HookEventSchema = z.enum([\"before_done\"]);\n\nexport const ConditionOperatorSchema = z.enum([\n \"file_exists\",\n \"file_contains\",\n \"env_var_set\",\n \"shell_returns_0\",\n]);\n\nexport const ConditionDefSchema = z.object({\n id: z.string().min(1),\n operator: ConditionOperatorSchema,\n path: z.string().optional(),\n contains: z.string().optional(),\n envVar: z.string().optional(),\n cmd: z.string().optional(),\n});\n\n/**\n * Per-item migration: handles legacy `trigger: { type, pattern }` → on/when\n * and legacy `manual:` field → `prompt:`.\n */\nfunction migrateLegacyCheckDef(raw: unknown): unknown {\n if (raw == null || typeof raw !== \"object\") return raw;\n const obj = raw as Record<string, unknown>;\n const result: Record<string, unknown> = { ...obj };\n\n // migrate trigger: { type, pattern } → on/when\n if (\"trigger\" in result && !(\"on\" in result) && !(\"when\" in result)) {\n const { trigger } = result;\n delete result.trigger;\n const t = trigger as Record<string, unknown>;\n if (t.type !== \"always\") {\n result.when = t.type === \"custom\" ? t.pattern : t.type;\n }\n }\n\n // migrate manual: → prompt:\n if (\"manual\" in result && !(\"prompt\" in result)) {\n result.prompt = result.manual;\n delete result.manual;\n }\n\n return result;\n}\n\n/**\n * Top-level migration: collapses ALL legacy array names into `checks:`.\n * Handles: deterministic, manual, task, prompt (any combination).\n * Existing `checks:` entries are preserved and come first.\n */\nfunction migrateLegacyConfig(raw: unknown): unknown {\n if (raw == null || typeof raw !== \"object\") return raw;\n const obj = raw as Record<string, unknown>;\n const result: Record<string, unknown> = { ...obj };\n\n const toArray = (key: string) => (Array.isArray(result[key]) ? (result[key] as unknown[]) : []);\n\n const merged = [\n ...toArray(\"checks\"),\n ...toArray(\"task\"),\n ...toArray(\"prompt\"),\n ...toArray(\"deterministic\"),\n ...toArray(\"manual\"),\n ].map(migrateLegacyCheckDef);\n\n if (\n \"checks\" in result ||\n \"task\" in result ||\n \"prompt\" in result ||\n \"deterministic\" in result ||\n \"manual\" in result\n ) {\n result.checks = merged;\n delete result.task;\n delete result.prompt;\n delete result.deterministic;\n delete result.manual;\n }\n\n return result;\n}\n\nexport const CheckDefSchema = z.preprocess(\n migrateLegacyCheckDef,\n z\n .object({\n id: z.string().min(1),\n label: z.string().min(1),\n on: HookEventSchema.optional(),\n when: z.string().optional(),\n cmd: z.string().optional(),\n prompt: z.string().optional(),\n conditionId: z.string().optional(),\n })\n .refine((c) => c.cmd !== undefined || c.prompt !== undefined, {\n message: \"A check must have either cmd (task) or prompt (agent instruction)\",\n }),\n);\n\nexport const HoldpointContextSchema = z.object({\n guides: z.record(z.string()).default({}),\n});\n\n/** Built-in scope names that cannot be overridden by user-defined patterns. */\nconst BUILTIN_SCOPES = new Set([\n \"frontend\",\n \"backend\",\n \"socket\",\n \"visual\",\n \"python\",\n \"go\",\n \"rust\",\n \"java\",\n \"ruby\",\n \"database\",\n \"prisma\",\n \"testing\",\n \"infra\",\n \"ci\",\n \"docs\",\n \"structural\",\n]);\n\nexport const HoldpointConfigSchema = z.preprocess(\n migrateLegacyConfig,\n z\n .object({\n version: z.number().int().positive().default(1),\n context: HoldpointContextSchema.default({ guides: {} }),\n conditions: z.array(ConditionDefSchema).default([]),\n checks: z.array(CheckDefSchema).default([]),\n patterns: z.record(z.string()).optional(),\n session_context_files: z.array(z.string()).optional(),\n })\n .superRefine((data, ctx) => {\n if (!data.patterns) return;\n for (const [key, value] of Object.entries(data.patterns)) {\n if (BUILTIN_SCOPES.has(key)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `'${key}' is a built-in scope name and cannot be redefined in patterns`,\n path: [\"patterns\", key],\n });\n }\n try {\n new RegExp(value);\n } catch {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Invalid regex in patterns.${key}: '${value}'`,\n path: [\"patterns\", key],\n });\n }\n }\n }),\n);\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/parser.ts","../src/schema.ts"],"sourcesContent":["import * as yaml from \"js-yaml\";\nimport type { HoldpointConfig, ValidationResult } from \"@holdpoint/types\";\nimport { HoldpointConfigSchema } from \"./schema.js\";\n\n/**\n * Parse a checks.yaml text into a HoldpointConfig.\n * Throws on invalid YAML or schema violations.\n */\nexport function parseHoldpointYaml(text: string): HoldpointConfig {\n const raw = yaml.load(text);\n const result = HoldpointConfigSchema.safeParse(raw);\n if (!result.success) {\n const messages = result.error.issues.map((e) => `${e.path.join(\".\")}: ${e.message}`).join(\"\\n\");\n throw new Error(`Invalid checks.yaml:\\n${messages}`);\n }\n return result.data as HoldpointConfig;\n}\n\n/**\n * Validate a parsed HoldpointConfig, returning structured errors.\n */\nexport function validateConfig(config: HoldpointConfig): ValidationResult {\n const result = HoldpointConfigSchema.safeParse(config);\n if (result.success) {\n return { valid: true, errors: [] };\n }\n return {\n valid: false,\n errors: result.error.issues.map((e) => ({\n path: e.path.join(\".\"),\n message: e.message,\n })),\n };\n}\n\n/**\n * Serialize a HoldpointConfig back to YAML text.\n */\nexport function generateYaml(config: HoldpointConfig): string {\n return yaml.dump(config, {\n indent: 2,\n lineWidth: 120,\n quotingType: '\"',\n forceQuotes: false,\n noRefs: true,\n });\n}\n","import { z } from \"zod\";\n\n// ─── Zod schemas ─────────────────────────────────────────────────────────────\n\nexport const HookEventSchema = z.enum([\n \"session_start\",\n \"message_submit\",\n \"before_tool\",\n \"after_tool\",\n \"session_end\",\n \"before_done\",\n]);\n\nexport const InjectSpecSchema = z\n .object({\n text: z.string().optional(),\n files: z.array(z.string()).optional(),\n datetime: z.boolean().optional(),\n })\n .refine((i) => i.text !== undefined || (i.files?.length ?? 0) > 0 || i.datetime === true, {\n message: \"inject must set at least one of text, files, or datetime\",\n });\n\nexport const ConditionOperatorSchema = z.enum([\n \"file_exists\",\n \"file_contains\",\n \"env_var_set\",\n \"shell_returns_0\",\n]);\n\nexport const ConditionDefSchema = z.object({\n id: z.string().min(1),\n operator: ConditionOperatorSchema,\n path: z.string().optional(),\n contains: z.string().optional(),\n envVar: z.string().optional(),\n cmd: z.string().optional(),\n});\n\n/**\n * Per-item migration: handles legacy `trigger: { type, pattern }` → on/when\n * and legacy `manual:` field → `prompt:`.\n */\nfunction migrateLegacyCheckDef(raw: unknown): unknown {\n if (raw == null || typeof raw !== \"object\") return raw;\n const obj = raw as Record<string, unknown>;\n const result: Record<string, unknown> = { ...obj };\n\n // migrate trigger: { type, pattern } → on/when\n if (\"trigger\" in result && !(\"on\" in result) && !(\"when\" in result)) {\n const { trigger } = result;\n delete result.trigger;\n const t = trigger as Record<string, unknown>;\n if (t.type !== \"always\") {\n result.when = t.type === \"custom\" ? t.pattern : t.type;\n }\n }\n\n // migrate manual: → prompt:\n if (\"manual\" in result && !(\"prompt\" in result)) {\n result.prompt = result.manual;\n delete result.manual;\n }\n\n return result;\n}\n\n/**\n * Top-level migration: collapses ALL legacy array names into `checks:`.\n * Handles: deterministic, manual, task, prompt (any combination).\n * Existing `checks:` entries are preserved and come first.\n */\nfunction migrateLegacyConfig(raw: unknown): unknown {\n if (raw == null || typeof raw !== \"object\") return raw;\n const obj = raw as Record<string, unknown>;\n const result: Record<string, unknown> = { ...obj };\n\n const toArray = (key: string) => (Array.isArray(result[key]) ? (result[key] as unknown[]) : []);\n\n const merged = [\n ...toArray(\"checks\"),\n ...toArray(\"task\"),\n ...toArray(\"prompt\"),\n ...toArray(\"deterministic\"),\n ...toArray(\"manual\"),\n ].map(migrateLegacyCheckDef);\n\n if (\n \"checks\" in result ||\n \"task\" in result ||\n \"prompt\" in result ||\n \"deterministic\" in result ||\n \"manual\" in result\n ) {\n result.checks = merged;\n delete result.task;\n delete result.prompt;\n delete result.deterministic;\n delete result.manual;\n }\n\n return result;\n}\n\nexport const CheckDefSchema = z.preprocess(\n migrateLegacyCheckDef,\n z\n .object({\n id: z.string().min(1),\n label: z.string().min(1),\n on: HookEventSchema.optional(),\n when: z.string().optional(),\n cmd: z.string().optional(),\n prompt: z.string().optional(),\n inject: InjectSpecSchema.optional(),\n conditionId: z.string().optional(),\n })\n .refine(\n (c) =>\n [c.cmd !== undefined, c.prompt !== undefined, c.inject !== undefined].filter(Boolean)\n .length === 1,\n {\n message:\n \"A check must have exactly one of cmd (command), prompt (agent instruction), or inject (context)\",\n },\n ),\n);\n\nexport const HoldpointContextSchema = z.object({\n guides: z.record(z.string(), z.string()).default({}),\n});\n\n/** Built-in scope names that cannot be overridden by user-defined patterns. */\nconst BUILTIN_SCOPES = new Set([\n \"frontend\",\n \"backend\",\n \"socket\",\n \"visual\",\n \"python\",\n \"go\",\n \"rust\",\n \"java\",\n \"ruby\",\n \"database\",\n \"prisma\",\n \"testing\",\n \"infra\",\n \"ci\",\n \"docs\",\n \"structural\",\n]);\n\nconst EnginesConfigSchema = z\n .object({\n claude: z\n .object({\n stop_command: z.string().optional(),\n live_command: z.string().optional(),\n })\n .optional(),\n codex: z.object({ stop_command: z.string().optional() }).optional(),\n copilot: z.object({ check_command: z.string().optional() }).optional(),\n })\n .optional();\n\nexport const HoldpointConfigSchema = z.preprocess(\n migrateLegacyConfig,\n z\n .object({\n version: z.number().int().positive().default(1),\n context: HoldpointContextSchema.default({ guides: {} }),\n conditions: z.array(ConditionDefSchema).default([]),\n checks: z.array(CheckDefSchema).default([]),\n patterns: z.record(z.string(), z.string()).optional(),\n session_context_files: z.array(z.string()).optional(),\n inject_datetime: z.boolean().optional(),\n engines: EnginesConfigSchema,\n })\n .superRefine((data, ctx) => {\n if (!data.patterns) return;\n for (const [key, value] of Object.entries(data.patterns)) {\n if (BUILTIN_SCOPES.has(key)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `'${key}' is a built-in scope name and cannot be redefined in patterns`,\n path: [\"patterns\", key],\n });\n }\n try {\n new RegExp(value);\n } catch {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Invalid regex in patterns.${key}: '${value}'`,\n path: [\"patterns\", key],\n });\n }\n }\n }),\n);\n"],"mappings":"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","names":[]}
|
package/dist/runner-entry.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { HoldpointConfig, CheckResult } from '@holdpoint/types';
|
|
1
|
+
import { HoldpointConfig, HookEvent, CheckResult } from '@holdpoint/types';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Run
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Run task checks (those with cmd) for a given hook against the changed files.
|
|
5
|
+
* Only checks whose effective hook matches `hook` run (default `before_done`,
|
|
6
|
+
* which preserves the completion-gate behavior). Checks whose trigger doesn't
|
|
7
|
+
* match, or whose condition is false, are skipped.
|
|
7
8
|
*/
|
|
8
|
-
declare function runDeterministicChecks(config: HoldpointConfig, changedFiles: string[]): CheckResult[];
|
|
9
|
+
declare function runDeterministicChecks(config: HoldpointConfig, changedFiles: string[], hook?: HookEvent): CheckResult[];
|
|
9
10
|
|
|
10
11
|
export { runDeterministicChecks };
|
package/dist/runner-entry.js
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
// src/runner.ts
|
|
6
6
|
import { execSync } from "child_process";
|
|
7
7
|
import { existsSync, readFileSync } from "fs";
|
|
8
|
+
import { checkHook } from "@holdpoint/types";
|
|
8
9
|
function evaluateCondition(condition) {
|
|
9
10
|
switch (condition.operator) {
|
|
10
11
|
case "file_exists":
|
|
@@ -45,9 +46,9 @@ function runCheck(check) {
|
|
|
45
46
|
return { check, status: "fail", output, exitCode: e.status ?? 1 };
|
|
46
47
|
}
|
|
47
48
|
}
|
|
48
|
-
function runDeterministicChecks(config, changedFiles) {
|
|
49
|
+
function runDeterministicChecks(config, changedFiles, hook = "before_done") {
|
|
49
50
|
const conditionMap = new Map(config.conditions.map((c) => [c.id, c]));
|
|
50
|
-
const taskChecks = config.checks.filter((c) => c.cmd !== void 0);
|
|
51
|
+
const taskChecks = config.checks.filter((c) => c.cmd !== void 0 && checkHook(c) === hook);
|
|
51
52
|
return taskChecks.map((check) => {
|
|
52
53
|
if (!matchesWhen(check.when, changedFiles, config.patterns)) {
|
|
53
54
|
return {
|
package/dist/runner-entry.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/runner.ts"],"sourcesContent":["import { execSync } from \"node:child_process\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport type {
|
|
1
|
+
{"version":3,"sources":["../src/runner.ts"],"sourcesContent":["import { execSync } from \"node:child_process\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport type {\n CheckDef,\n CheckResult,\n ConditionDef,\n HoldpointConfig,\n HookEvent,\n} from \"@holdpoint/types\";\nimport { checkHook } from \"@holdpoint/types\";\nimport { matchesWhen } from \"./trigger.js\";\n\nfunction evaluateCondition(condition: ConditionDef): boolean {\n switch (condition.operator) {\n case \"file_exists\":\n return condition.path != null && existsSync(condition.path);\n\n case \"file_contains\": {\n if (!condition.path || !condition.contains) return false;\n if (!existsSync(condition.path)) return false;\n const content = readFileSync(condition.path, \"utf8\");\n return content.includes(condition.contains);\n }\n\n case \"env_var_set\":\n return condition.envVar != null && process.env[condition.envVar] !== undefined;\n\n case \"shell_returns_0\": {\n if (!condition.cmd) return false;\n try {\n execSync(condition.cmd, { stdio: \"ignore\" });\n return true;\n } catch {\n return false;\n }\n }\n }\n}\n\nfunction runCheck(check: CheckDef): CheckResult {\n if (!check.cmd) {\n return { check, status: \"pending\" };\n }\n try {\n const output = execSync(check.cmd, {\n stdio: \"pipe\",\n encoding: \"utf8\",\n timeout: 60_000,\n });\n return { check, status: \"pass\", output, exitCode: 0 };\n } catch (err: unknown) {\n const e = err as { stdout?: string; stderr?: string; status?: number };\n const output = [e.stdout, e.stderr].filter(Boolean).join(\"\\n\");\n return { check, status: \"fail\", output, exitCode: e.status ?? 1 };\n }\n}\n\n/**\n * Run task checks (those with cmd) for a given hook against the changed files.\n * Only checks whose effective hook matches `hook` run (default `before_done`,\n * which preserves the completion-gate behavior). Checks whose trigger doesn't\n * match, or whose condition is false, are skipped.\n */\nexport function runDeterministicChecks(\n config: HoldpointConfig,\n changedFiles: string[],\n hook: HookEvent = \"before_done\",\n): CheckResult[] {\n const conditionMap = new Map(config.conditions.map((c) => [c.id, c]));\n const taskChecks = config.checks.filter((c) => c.cmd !== undefined && checkHook(c) === hook);\n\n return taskChecks.map((check) => {\n if (!matchesWhen(check.when, changedFiles, config.patterns)) {\n return {\n check,\n status: \"skip\",\n skipReason: `'when: ${check.when}' did not match changed files`,\n };\n }\n\n if (check.conditionId) {\n const condition = conditionMap.get(check.conditionId);\n if (!condition) {\n return {\n check,\n status: \"skip\",\n skipReason: `Condition '${check.conditionId}' not found`,\n };\n }\n if (!evaluateCondition(condition)) {\n return {\n check,\n status: \"skip\",\n skipReason: `Condition '${check.conditionId}' evaluated to false`,\n };\n }\n }\n\n return runCheck(check);\n });\n}\n"],"mappings":";;;;;AAAA,SAAS,gBAAgB;AACzB,SAAS,YAAY,oBAAoB;AAQzC,SAAS,iBAAiB;AAG1B,SAAS,kBAAkB,WAAkC;AAC3D,UAAQ,UAAU,UAAU;AAAA,IAC1B,KAAK;AACH,aAAO,UAAU,QAAQ,QAAQ,WAAW,UAAU,IAAI;AAAA,IAE5D,KAAK,iBAAiB;AACpB,UAAI,CAAC,UAAU,QAAQ,CAAC,UAAU,SAAU,QAAO;AACnD,UAAI,CAAC,WAAW,UAAU,IAAI,EAAG,QAAO;AACxC,YAAM,UAAU,aAAa,UAAU,MAAM,MAAM;AACnD,aAAO,QAAQ,SAAS,UAAU,QAAQ;AAAA,IAC5C;AAAA,IAEA,KAAK;AACH,aAAO,UAAU,UAAU,QAAQ,QAAQ,IAAI,UAAU,MAAM,MAAM;AAAA,IAEvE,KAAK,mBAAmB;AACtB,UAAI,CAAC,UAAU,IAAK,QAAO;AAC3B,UAAI;AACF,iBAAS,UAAU,KAAK,EAAE,OAAO,SAAS,CAAC;AAC3C,eAAO;AAAA,MACT,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,SAAS,OAA8B;AAC9C,MAAI,CAAC,MAAM,KAAK;AACd,WAAO,EAAE,OAAO,QAAQ,UAAU;AAAA,EACpC;AACA,MAAI;AACF,UAAM,SAAS,SAAS,MAAM,KAAK;AAAA,MACjC,OAAO;AAAA,MACP,UAAU;AAAA,MACV,SAAS;AAAA,IACX,CAAC;AACD,WAAO,EAAE,OAAO,QAAQ,QAAQ,QAAQ,UAAU,EAAE;AAAA,EACtD,SAAS,KAAc;AACrB,UAAM,IAAI;AACV,UAAM,SAAS,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI;AAC7D,WAAO,EAAE,OAAO,QAAQ,QAAQ,QAAQ,UAAU,EAAE,UAAU,EAAE;AAAA,EAClE;AACF;AAQO,SAAS,uBACd,QACA,cACA,OAAkB,eACH;AACf,QAAM,eAAe,IAAI,IAAI,OAAO,WAAW,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AACpE,QAAM,aAAa,OAAO,OAAO,OAAO,CAAC,MAAM,EAAE,QAAQ,UAAa,UAAU,CAAC,MAAM,IAAI;AAE3F,SAAO,WAAW,IAAI,CAAC,UAAU;AAC/B,QAAI,CAAC,YAAY,MAAM,MAAM,cAAc,OAAO,QAAQ,GAAG;AAC3D,aAAO;AAAA,QACL;AAAA,QACA,QAAQ;AAAA,QACR,YAAY,UAAU,MAAM,IAAI;AAAA,MAClC;AAAA,IACF;AAEA,QAAI,MAAM,aAAa;AACrB,YAAM,YAAY,aAAa,IAAI,MAAM,WAAW;AACpD,UAAI,CAAC,WAAW;AACd,eAAO;AAAA,UACL;AAAA,UACA,QAAQ;AAAA,UACR,YAAY,cAAc,MAAM,WAAW;AAAA,QAC7C;AAAA,MACF;AACA,UAAI,CAAC,kBAAkB,SAAS,GAAG;AACjC,eAAO;AAAA,UACL;AAAA,UACA,QAAQ;AAAA,UACR,YAAY,cAAc,MAAM,WAAW;AAAA,QAC7C;AAAA,MACF;AAAA,IACF;AAEA,WAAO,SAAS,KAAK;AAAA,EACvB,CAAC;AACH;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@holdpoint/yaml-core",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.11",
|
|
4
4
|
"publishConfig": {
|
|
5
|
-
"access": "public"
|
|
6
|
-
"tag": "alpha"
|
|
5
|
+
"access": "public"
|
|
7
6
|
},
|
|
8
7
|
"description": "Shared checks.yaml parser, validator, trigger matcher and runner",
|
|
9
8
|
"homepage": "https://holdpoint.dev",
|
|
@@ -49,15 +48,15 @@
|
|
|
49
48
|
"dependencies": {
|
|
50
49
|
"js-yaml": "^4.1.0",
|
|
51
50
|
"minimatch": "^10.0.1",
|
|
52
|
-
"zod": "^
|
|
53
|
-
"@holdpoint/types": "0.1.0-alpha.
|
|
51
|
+
"zod": "^4.4.3",
|
|
52
|
+
"@holdpoint/types": "0.1.0-alpha.10"
|
|
54
53
|
},
|
|
55
54
|
"devDependencies": {
|
|
56
55
|
"@types/js-yaml": "^4.0.9",
|
|
57
|
-
"@types/node": "^
|
|
56
|
+
"@types/node": "^25.9.1",
|
|
58
57
|
"tsup": "^8.3.5",
|
|
59
|
-
"typescript": "^
|
|
60
|
-
"vitest": "^
|
|
58
|
+
"typescript": "^6.0.3",
|
|
59
|
+
"vitest": "^4.1.7"
|
|
61
60
|
},
|
|
62
61
|
"scripts": {
|
|
63
62
|
"build": "tsup",
|