@holdpoint/yaml-core 0.1.0-alpha.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/dist/chunk-IWY4DYCT.js +158 -0
- package/dist/chunk-IWY4DYCT.js.map +1 -0
- package/dist/index.d.ts +287 -0
- package/dist/index.js +174 -0
- package/dist/index.js.map +1 -0
- package/dist/runner-entry.d.ts +10 -0
- package/dist/runner-entry.js +82 -0
- package/dist/runner-entry.js.map +1 -0
- package/package.json +69 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
// src/trigger.ts
|
|
2
|
+
import { minimatch } from "minimatch";
|
|
3
|
+
var SCOPE_PATTERNS = {
|
|
4
|
+
// ── Web / app layers ────────────────────────────────────────────────────────
|
|
5
|
+
frontend: [
|
|
6
|
+
"**/*.tsx",
|
|
7
|
+
"**/*.jsx",
|
|
8
|
+
"**/*.css",
|
|
9
|
+
"**/*.scss",
|
|
10
|
+
"**/tailwind.config.*",
|
|
11
|
+
"**/postcss.config.*",
|
|
12
|
+
"apps/builder/**",
|
|
13
|
+
"apps/web/**"
|
|
14
|
+
],
|
|
15
|
+
backend: [
|
|
16
|
+
"**/api/**",
|
|
17
|
+
"**/server/**",
|
|
18
|
+
"**/routes/**",
|
|
19
|
+
"**/controllers/**",
|
|
20
|
+
"**/middleware/**",
|
|
21
|
+
"packages/*/src/**"
|
|
22
|
+
],
|
|
23
|
+
socket: ["**/socket/**", "**/ws/**", "**/websocket/**"],
|
|
24
|
+
visual: ["**/*.stories.tsx", "**/*.stories.ts", "**/__screenshots__/**", "**/*.snap"],
|
|
25
|
+
// ── Languages ────────────────────────────────────────────────────────────────
|
|
26
|
+
python: [
|
|
27
|
+
"**/*.py",
|
|
28
|
+
"**/*.pyi",
|
|
29
|
+
"**/requirements*.txt",
|
|
30
|
+
"**/pyproject.toml",
|
|
31
|
+
"**/setup.py",
|
|
32
|
+
"**/setup.cfg",
|
|
33
|
+
"**/Pipfile",
|
|
34
|
+
"**/uv.lock",
|
|
35
|
+
"**/pytest.ini",
|
|
36
|
+
"**/tox.ini"
|
|
37
|
+
],
|
|
38
|
+
go: ["**/*.go", "**/go.mod", "**/go.sum"],
|
|
39
|
+
rust: ["**/*.rs", "**/Cargo.toml", "**/Cargo.lock"],
|
|
40
|
+
java: ["**/*.java", "**/*.kt", "**/*.gradle", "**/*.gradle.kts", "**/pom.xml"],
|
|
41
|
+
ruby: ["**/*.rb", "**/Gemfile", "**/Gemfile.lock", "**/Rakefile"],
|
|
42
|
+
// ── Cross-cutting concerns ───────────────────────────────────────────────────
|
|
43
|
+
database: [
|
|
44
|
+
"**/*.sql",
|
|
45
|
+
"**/migrations/**",
|
|
46
|
+
"**/migration/**",
|
|
47
|
+
"**/prisma/**",
|
|
48
|
+
"**/*.prisma",
|
|
49
|
+
"**/db/**",
|
|
50
|
+
"**/database/**",
|
|
51
|
+
"**/seeds/**",
|
|
52
|
+
"**/seed/**",
|
|
53
|
+
"**/alembic.ini"
|
|
54
|
+
],
|
|
55
|
+
// prisma is kept as a focused subset of database for Prisma-specific checks
|
|
56
|
+
prisma: ["**/prisma/**", "**/*.prisma"],
|
|
57
|
+
testing: [
|
|
58
|
+
"**/*.test.ts",
|
|
59
|
+
"**/*.test.tsx",
|
|
60
|
+
"**/*.test.js",
|
|
61
|
+
"**/*.test.jsx",
|
|
62
|
+
"**/*.test.py",
|
|
63
|
+
"**/*.test.rb",
|
|
64
|
+
"**/*.test.go",
|
|
65
|
+
"**/*.spec.ts",
|
|
66
|
+
"**/*.spec.tsx",
|
|
67
|
+
"**/*.spec.js",
|
|
68
|
+
"**/__tests__/**",
|
|
69
|
+
"**/test/**",
|
|
70
|
+
"**/tests/**",
|
|
71
|
+
"**/spec/**"
|
|
72
|
+
],
|
|
73
|
+
infra: [
|
|
74
|
+
"**/Dockerfile",
|
|
75
|
+
"**/Dockerfile.*",
|
|
76
|
+
"**/docker-compose.*",
|
|
77
|
+
"**/*.tf",
|
|
78
|
+
"**/*.tfvars",
|
|
79
|
+
"**/*.hcl",
|
|
80
|
+
"**/k8s/**",
|
|
81
|
+
"**/kubernetes/**",
|
|
82
|
+
"**/helm/**",
|
|
83
|
+
"**/charts/**",
|
|
84
|
+
"**/.dockerignore"
|
|
85
|
+
],
|
|
86
|
+
ci: [
|
|
87
|
+
"**/.github/workflows/**",
|
|
88
|
+
"**/.circleci/**",
|
|
89
|
+
"**/Jenkinsfile",
|
|
90
|
+
"**/.gitlab-ci.yml",
|
|
91
|
+
"**/.travis.yml",
|
|
92
|
+
"**/.drone.yml"
|
|
93
|
+
],
|
|
94
|
+
docs: ["**/*.mdx", "**/*.rst", "**/docs/**", "**/documentation/**"],
|
|
95
|
+
// ── Project structure / dependency manifests ─────────────────────────────────
|
|
96
|
+
// Covers any file whose change signals that the project's dependency graph,
|
|
97
|
+
// toolchain config, CI pipeline, or API contract has shifted — i.e. the checks
|
|
98
|
+
// themselves may need to evolve to stay in sync.
|
|
99
|
+
structural: [
|
|
100
|
+
"**/package.json",
|
|
101
|
+
"**/tsconfig*.json",
|
|
102
|
+
"**/requirements*.txt",
|
|
103
|
+
"**/pyproject.toml",
|
|
104
|
+
"**/Pipfile",
|
|
105
|
+
"**/setup.py",
|
|
106
|
+
"**/setup.cfg",
|
|
107
|
+
"**/pytest.ini",
|
|
108
|
+
"**/tox.ini",
|
|
109
|
+
"**/go.mod",
|
|
110
|
+
"**/Cargo.toml",
|
|
111
|
+
"**/pom.xml",
|
|
112
|
+
"**/build.gradle",
|
|
113
|
+
"**/build.gradle.kts",
|
|
114
|
+
"**/Gemfile",
|
|
115
|
+
"**/vitest.config.*",
|
|
116
|
+
"**/jest.config.*",
|
|
117
|
+
"**/playwright.config.*",
|
|
118
|
+
"**/eslint.config.*",
|
|
119
|
+
"**/.eslintrc*",
|
|
120
|
+
"**/biome.json",
|
|
121
|
+
"**/prettier.config.*",
|
|
122
|
+
"**/.prettierrc*",
|
|
123
|
+
"**/next.config.*",
|
|
124
|
+
"**/Dockerfile*",
|
|
125
|
+
"**/docker-compose*.yml",
|
|
126
|
+
"**/docker-compose*.yaml",
|
|
127
|
+
"**/*.tf",
|
|
128
|
+
"**/prisma/schema.prisma",
|
|
129
|
+
"**/openapi.yaml",
|
|
130
|
+
"**/openapi.yml",
|
|
131
|
+
"**/openapi.json",
|
|
132
|
+
"**/.github/workflows/*.yml",
|
|
133
|
+
"**/.github/workflows/*.yaml",
|
|
134
|
+
"**/.circleci/**",
|
|
135
|
+
"**/Jenkinsfile",
|
|
136
|
+
"**/.gitlab-ci.yml",
|
|
137
|
+
"**/.travis.yml"
|
|
138
|
+
]
|
|
139
|
+
};
|
|
140
|
+
function matchesWhen(when, changedFiles, userPatterns) {
|
|
141
|
+
if (!when) return true;
|
|
142
|
+
if (changedFiles.includes("__all__")) return true;
|
|
143
|
+
if (when in SCOPE_PATTERNS) {
|
|
144
|
+
const globs = SCOPE_PATTERNS[when];
|
|
145
|
+
return changedFiles.some((file) => globs.some((glob) => minimatch(file, glob)));
|
|
146
|
+
}
|
|
147
|
+
if (userPatterns && when in userPatterns) {
|
|
148
|
+
const re2 = new RegExp(userPatterns[when]);
|
|
149
|
+
return changedFiles.some((f) => re2.test(f));
|
|
150
|
+
}
|
|
151
|
+
const re = new RegExp(when);
|
|
152
|
+
return changedFiles.some((f) => re.test(f));
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export {
|
|
156
|
+
matchesWhen
|
|
157
|
+
};
|
|
158
|
+
//# sourceMappingURL=chunk-IWY4DYCT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/trigger.ts"],"sourcesContent":["import { minimatch } from \"minimatch\";\n\nconst SCOPE_PATTERNS: Record<string, string[]> = {\n // ── Web / app layers ────────────────────────────────────────────────────────\n frontend: [\n \"**/*.tsx\",\n \"**/*.jsx\",\n \"**/*.css\",\n \"**/*.scss\",\n \"**/tailwind.config.*\",\n \"**/postcss.config.*\",\n \"apps/builder/**\",\n \"apps/web/**\",\n ],\n backend: [\n \"**/api/**\",\n \"**/server/**\",\n \"**/routes/**\",\n \"**/controllers/**\",\n \"**/middleware/**\",\n \"packages/*/src/**\",\n ],\n socket: [\"**/socket/**\", \"**/ws/**\", \"**/websocket/**\"],\n visual: [\"**/*.stories.tsx\", \"**/*.stories.ts\", \"**/__screenshots__/**\", \"**/*.snap\"],\n\n // ── Languages ────────────────────────────────────────────────────────────────\n python: [\n \"**/*.py\",\n \"**/*.pyi\",\n \"**/requirements*.txt\",\n \"**/pyproject.toml\",\n \"**/setup.py\",\n \"**/setup.cfg\",\n \"**/Pipfile\",\n \"**/uv.lock\",\n \"**/pytest.ini\",\n \"**/tox.ini\",\n ],\n go: [\"**/*.go\", \"**/go.mod\", \"**/go.sum\"],\n rust: [\"**/*.rs\", \"**/Cargo.toml\", \"**/Cargo.lock\"],\n java: [\"**/*.java\", \"**/*.kt\", \"**/*.gradle\", \"**/*.gradle.kts\", \"**/pom.xml\"],\n ruby: [\"**/*.rb\", \"**/Gemfile\", \"**/Gemfile.lock\", \"**/Rakefile\"],\n\n // ── Cross-cutting concerns ───────────────────────────────────────────────────\n database: [\n \"**/*.sql\",\n \"**/migrations/**\",\n \"**/migration/**\",\n \"**/prisma/**\",\n \"**/*.prisma\",\n \"**/db/**\",\n \"**/database/**\",\n \"**/seeds/**\",\n \"**/seed/**\",\n \"**/alembic.ini\",\n ],\n // prisma is kept as a focused subset of database for Prisma-specific checks\n prisma: [\"**/prisma/**\", \"**/*.prisma\"],\n testing: [\n \"**/*.test.ts\",\n \"**/*.test.tsx\",\n \"**/*.test.js\",\n \"**/*.test.jsx\",\n \"**/*.test.py\",\n \"**/*.test.rb\",\n \"**/*.test.go\",\n \"**/*.spec.ts\",\n \"**/*.spec.tsx\",\n \"**/*.spec.js\",\n \"**/__tests__/**\",\n \"**/test/**\",\n \"**/tests/**\",\n \"**/spec/**\",\n ],\n infra: [\n \"**/Dockerfile\",\n \"**/Dockerfile.*\",\n \"**/docker-compose.*\",\n \"**/*.tf\",\n \"**/*.tfvars\",\n \"**/*.hcl\",\n \"**/k8s/**\",\n \"**/kubernetes/**\",\n \"**/helm/**\",\n \"**/charts/**\",\n \"**/.dockerignore\",\n ],\n ci: [\n \"**/.github/workflows/**\",\n \"**/.circleci/**\",\n \"**/Jenkinsfile\",\n \"**/.gitlab-ci.yml\",\n \"**/.travis.yml\",\n \"**/.drone.yml\",\n ],\n docs: [\"**/*.mdx\", \"**/*.rst\", \"**/docs/**\", \"**/documentation/**\"],\n\n // ── Project structure / dependency manifests ─────────────────────────────────\n // Covers any file whose change signals that the project's dependency graph,\n // toolchain config, CI pipeline, or API contract has shifted — i.e. the checks\n // themselves may need to evolve to stay in sync.\n structural: [\n \"**/package.json\",\n \"**/tsconfig*.json\",\n \"**/requirements*.txt\",\n \"**/pyproject.toml\",\n \"**/Pipfile\",\n \"**/setup.py\",\n \"**/setup.cfg\",\n \"**/pytest.ini\",\n \"**/tox.ini\",\n \"**/go.mod\",\n \"**/Cargo.toml\",\n \"**/pom.xml\",\n \"**/build.gradle\",\n \"**/build.gradle.kts\",\n \"**/Gemfile\",\n \"**/vitest.config.*\",\n \"**/jest.config.*\",\n \"**/playwright.config.*\",\n \"**/eslint.config.*\",\n \"**/.eslintrc*\",\n \"**/biome.json\",\n \"**/prettier.config.*\",\n \"**/.prettierrc*\",\n \"**/next.config.*\",\n \"**/Dockerfile*\",\n \"**/docker-compose*.yml\",\n \"**/docker-compose*.yaml\",\n \"**/*.tf\",\n \"**/prisma/schema.prisma\",\n \"**/openapi.yaml\",\n \"**/openapi.yml\",\n \"**/openapi.json\",\n \"**/.github/workflows/*.yml\",\n \"**/.github/workflows/*.yaml\",\n \"**/.circleci/**\",\n \"**/Jenkinsfile\",\n \"**/.gitlab-ci.yml\",\n \"**/.travis.yml\",\n ],\n};\n\n/**\n * Returns true if any of the changedFiles match the given when filter.\n * - `undefined` → always matches (no filter)\n * - named scope (\"frontend\", \"backend\", \"structural\", …) → minimatch glob match\n * - key in userPatterns → regex match using the resolved pattern string\n * - any other string → treated as a raw regex\n */\nexport function matchesWhen(\n when: string | undefined,\n changedFiles: string[],\n userPatterns?: Record<string, string>,\n): boolean {\n if (!when) return true;\n // \"__all__\" holdpoint value means no staged files — run all checks unconditionally\n if (changedFiles.includes(\"__all__\")) return true;\n\n if (when in SCOPE_PATTERNS) {\n const globs = SCOPE_PATTERNS[when]!;\n return changedFiles.some((file) => globs.some((glob) => minimatch(file, glob)));\n }\n\n // User-defined named patterns (regex-based)\n if (userPatterns && when in userPatterns) {\n const re = new RegExp(userPatterns[when]!);\n return changedFiles.some((f) => re.test(f));\n }\n\n // Raw regex fallback\n const re = new RegExp(when);\n return changedFiles.some((f) => re.test(f));\n}\n"],"mappings":"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","names":["re"]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import { HoldpointConfig, ValidationResult } from '@holdpoint/types';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Parse a checks.yaml text into a HoldpointConfig.
|
|
6
|
+
* Throws on invalid YAML or schema violations.
|
|
7
|
+
*/
|
|
8
|
+
declare function parseHoldpointYaml(text: string): HoldpointConfig;
|
|
9
|
+
/**
|
|
10
|
+
* Validate a parsed HoldpointConfig, returning structured errors.
|
|
11
|
+
*/
|
|
12
|
+
declare function validateConfig(config: HoldpointConfig): ValidationResult;
|
|
13
|
+
/**
|
|
14
|
+
* Serialize a HoldpointConfig back to YAML text.
|
|
15
|
+
*/
|
|
16
|
+
declare function generateYaml(config: HoldpointConfig): string;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Returns true if any of the changedFiles match the given when filter.
|
|
20
|
+
* - `undefined` → always matches (no filter)
|
|
21
|
+
* - named scope ("frontend", "backend", "structural", …) → minimatch glob match
|
|
22
|
+
* - key in userPatterns → regex match using the resolved pattern string
|
|
23
|
+
* - any other string → treated as a raw regex
|
|
24
|
+
*/
|
|
25
|
+
declare function matchesWhen(when: string | undefined, changedFiles: string[], userPatterns?: Record<string, string>): boolean;
|
|
26
|
+
|
|
27
|
+
declare const HookEventSchema: z.ZodEnum<["before_done"]>;
|
|
28
|
+
declare const ConditionDefSchema: z.ZodObject<{
|
|
29
|
+
id: z.ZodString;
|
|
30
|
+
operator: z.ZodEnum<["file_exists", "file_contains", "env_var_set", "shell_returns_0"]>;
|
|
31
|
+
path: z.ZodOptional<z.ZodString>;
|
|
32
|
+
contains: z.ZodOptional<z.ZodString>;
|
|
33
|
+
envVar: z.ZodOptional<z.ZodString>;
|
|
34
|
+
cmd: z.ZodOptional<z.ZodString>;
|
|
35
|
+
}, "strip", z.ZodTypeAny, {
|
|
36
|
+
id: string;
|
|
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<{
|
|
51
|
+
id: z.ZodString;
|
|
52
|
+
label: z.ZodString;
|
|
53
|
+
on: z.ZodOptional<z.ZodEnum<["before_done"]>>;
|
|
54
|
+
when: z.ZodOptional<z.ZodString>;
|
|
55
|
+
cmd: z.ZodOptional<z.ZodString>;
|
|
56
|
+
prompt: z.ZodOptional<z.ZodString>;
|
|
57
|
+
conditionId: z.ZodOptional<z.ZodString>;
|
|
58
|
+
}, "strip", z.ZodTypeAny, {
|
|
59
|
+
id: string;
|
|
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<{
|
|
100
|
+
version: z.ZodDefault<z.ZodNumber>;
|
|
101
|
+
context: z.ZodDefault<z.ZodObject<{
|
|
102
|
+
guides: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
103
|
+
}, "strip", z.ZodTypeAny, {
|
|
104
|
+
guides: Record<string, string>;
|
|
105
|
+
}, {
|
|
106
|
+
guides?: Record<string, string> | undefined;
|
|
107
|
+
}>>;
|
|
108
|
+
conditions: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
109
|
+
id: z.ZodString;
|
|
110
|
+
operator: z.ZodEnum<["file_exists", "file_contains", "env_var_set", "shell_returns_0"]>;
|
|
111
|
+
path: z.ZodOptional<z.ZodString>;
|
|
112
|
+
contains: z.ZodOptional<z.ZodString>;
|
|
113
|
+
envVar: z.ZodOptional<z.ZodString>;
|
|
114
|
+
cmd: z.ZodOptional<z.ZodString>;
|
|
115
|
+
}, "strip", z.ZodTypeAny, {
|
|
116
|
+
id: string;
|
|
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<{
|
|
131
|
+
id: z.ZodString;
|
|
132
|
+
label: z.ZodString;
|
|
133
|
+
on: z.ZodOptional<z.ZodEnum<["before_done"]>>;
|
|
134
|
+
when: z.ZodOptional<z.ZodString>;
|
|
135
|
+
cmd: z.ZodOptional<z.ZodString>;
|
|
136
|
+
prompt: z.ZodOptional<z.ZodString>;
|
|
137
|
+
conditionId: z.ZodOptional<z.ZodString>;
|
|
138
|
+
}, "strip", z.ZodTypeAny, {
|
|
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">>;
|
|
179
|
+
patterns: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
180
|
+
session_context_files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
181
|
+
}, "strip", z.ZodTypeAny, {
|
|
182
|
+
checks: {
|
|
183
|
+
id: string;
|
|
184
|
+
label: string;
|
|
185
|
+
cmd?: string | undefined;
|
|
186
|
+
on?: "before_done" | undefined;
|
|
187
|
+
when?: string | undefined;
|
|
188
|
+
prompt?: string | undefined;
|
|
189
|
+
conditionId?: string | undefined;
|
|
190
|
+
}[];
|
|
191
|
+
version: number;
|
|
192
|
+
context: {
|
|
193
|
+
guides: Record<string, string>;
|
|
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>;
|
|
286
|
+
|
|
287
|
+
export { CheckDefSchema, ConditionDefSchema, HoldpointConfigSchema, HookEventSchema, generateYaml, matchesWhen, parseHoldpointYaml, validateConfig };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import {
|
|
2
|
+
matchesWhen
|
|
3
|
+
} from "./chunk-IWY4DYCT.js";
|
|
4
|
+
|
|
5
|
+
// src/parser.ts
|
|
6
|
+
import * as yaml from "js-yaml";
|
|
7
|
+
|
|
8
|
+
// src/schema.ts
|
|
9
|
+
import { z } from "zod";
|
|
10
|
+
var HookEventSchema = z.enum(["before_done"]);
|
|
11
|
+
var ConditionOperatorSchema = z.enum([
|
|
12
|
+
"file_exists",
|
|
13
|
+
"file_contains",
|
|
14
|
+
"env_var_set",
|
|
15
|
+
"shell_returns_0"
|
|
16
|
+
]);
|
|
17
|
+
var ConditionDefSchema = z.object({
|
|
18
|
+
id: z.string().min(1),
|
|
19
|
+
operator: ConditionOperatorSchema,
|
|
20
|
+
path: z.string().optional(),
|
|
21
|
+
contains: z.string().optional(),
|
|
22
|
+
envVar: z.string().optional(),
|
|
23
|
+
cmd: z.string().optional()
|
|
24
|
+
});
|
|
25
|
+
function migrateLegacyCheckDef(raw) {
|
|
26
|
+
if (raw == null || typeof raw !== "object") return raw;
|
|
27
|
+
const obj = raw;
|
|
28
|
+
const result = { ...obj };
|
|
29
|
+
if ("trigger" in result && !("on" in result) && !("when" in result)) {
|
|
30
|
+
const { trigger } = result;
|
|
31
|
+
delete result.trigger;
|
|
32
|
+
const t = trigger;
|
|
33
|
+
if (t.type !== "always") {
|
|
34
|
+
result.when = t.type === "custom" ? t.pattern : t.type;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if ("manual" in result && !("prompt" in result)) {
|
|
38
|
+
result.prompt = result.manual;
|
|
39
|
+
delete result.manual;
|
|
40
|
+
}
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
function migrateLegacyConfig(raw) {
|
|
44
|
+
if (raw == null || typeof raw !== "object") return raw;
|
|
45
|
+
const obj = raw;
|
|
46
|
+
const result = { ...obj };
|
|
47
|
+
const toArray = (key) => Array.isArray(result[key]) ? result[key] : [];
|
|
48
|
+
const merged = [
|
|
49
|
+
...toArray("checks"),
|
|
50
|
+
...toArray("task"),
|
|
51
|
+
...toArray("prompt"),
|
|
52
|
+
...toArray("deterministic"),
|
|
53
|
+
...toArray("manual")
|
|
54
|
+
].map(migrateLegacyCheckDef);
|
|
55
|
+
if ("checks" in result || "task" in result || "prompt" in result || "deterministic" in result || "manual" in result) {
|
|
56
|
+
result.checks = merged;
|
|
57
|
+
delete result.task;
|
|
58
|
+
delete result.prompt;
|
|
59
|
+
delete result.deterministic;
|
|
60
|
+
delete result.manual;
|
|
61
|
+
}
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
var CheckDefSchema = z.preprocess(
|
|
65
|
+
migrateLegacyCheckDef,
|
|
66
|
+
z.object({
|
|
67
|
+
id: z.string().min(1),
|
|
68
|
+
label: z.string().min(1),
|
|
69
|
+
on: HookEventSchema.optional(),
|
|
70
|
+
when: z.string().optional(),
|
|
71
|
+
cmd: z.string().optional(),
|
|
72
|
+
prompt: z.string().optional(),
|
|
73
|
+
conditionId: z.string().optional()
|
|
74
|
+
}).refine((c) => c.cmd !== void 0 || c.prompt !== void 0, {
|
|
75
|
+
message: "A check must have either cmd (task) or prompt (agent instruction)"
|
|
76
|
+
})
|
|
77
|
+
);
|
|
78
|
+
var HoldpointContextSchema = z.object({
|
|
79
|
+
guides: z.record(z.string()).default({})
|
|
80
|
+
});
|
|
81
|
+
var BUILTIN_SCOPES = /* @__PURE__ */ new Set([
|
|
82
|
+
"frontend",
|
|
83
|
+
"backend",
|
|
84
|
+
"socket",
|
|
85
|
+
"visual",
|
|
86
|
+
"python",
|
|
87
|
+
"go",
|
|
88
|
+
"rust",
|
|
89
|
+
"java",
|
|
90
|
+
"ruby",
|
|
91
|
+
"database",
|
|
92
|
+
"prisma",
|
|
93
|
+
"testing",
|
|
94
|
+
"infra",
|
|
95
|
+
"ci",
|
|
96
|
+
"docs",
|
|
97
|
+
"structural"
|
|
98
|
+
]);
|
|
99
|
+
var HoldpointConfigSchema = z.preprocess(
|
|
100
|
+
migrateLegacyConfig,
|
|
101
|
+
z.object({
|
|
102
|
+
version: z.number().int().positive().default(1),
|
|
103
|
+
context: HoldpointContextSchema.default({ guides: {} }),
|
|
104
|
+
conditions: z.array(ConditionDefSchema).default([]),
|
|
105
|
+
checks: z.array(CheckDefSchema).default([]),
|
|
106
|
+
patterns: z.record(z.string()).optional(),
|
|
107
|
+
session_context_files: z.array(z.string()).optional()
|
|
108
|
+
}).superRefine((data, ctx) => {
|
|
109
|
+
if (!data.patterns) return;
|
|
110
|
+
for (const [key, value] of Object.entries(data.patterns)) {
|
|
111
|
+
if (BUILTIN_SCOPES.has(key)) {
|
|
112
|
+
ctx.addIssue({
|
|
113
|
+
code: z.ZodIssueCode.custom,
|
|
114
|
+
message: `'${key}' is a built-in scope name and cannot be redefined in patterns`,
|
|
115
|
+
path: ["patterns", key]
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
try {
|
|
119
|
+
new RegExp(value);
|
|
120
|
+
} catch {
|
|
121
|
+
ctx.addIssue({
|
|
122
|
+
code: z.ZodIssueCode.custom,
|
|
123
|
+
message: `Invalid regex in patterns.${key}: '${value}'`,
|
|
124
|
+
path: ["patterns", key]
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
})
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
// src/parser.ts
|
|
132
|
+
function parseHoldpointYaml(text) {
|
|
133
|
+
const raw = yaml.load(text);
|
|
134
|
+
const result = HoldpointConfigSchema.safeParse(raw);
|
|
135
|
+
if (!result.success) {
|
|
136
|
+
const messages = result.error.errors.map((e) => `${e.path.join(".")}: ${e.message}`).join("\n");
|
|
137
|
+
throw new Error(`Invalid checks.yaml:
|
|
138
|
+
${messages}`);
|
|
139
|
+
}
|
|
140
|
+
return result.data;
|
|
141
|
+
}
|
|
142
|
+
function validateConfig(config) {
|
|
143
|
+
const result = HoldpointConfigSchema.safeParse(config);
|
|
144
|
+
if (result.success) {
|
|
145
|
+
return { valid: true, errors: [] };
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
valid: false,
|
|
149
|
+
errors: result.error.errors.map((e) => ({
|
|
150
|
+
path: e.path.join("."),
|
|
151
|
+
message: e.message
|
|
152
|
+
}))
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
function generateYaml(config) {
|
|
156
|
+
return yaml.dump(config, {
|
|
157
|
+
indent: 2,
|
|
158
|
+
lineWidth: 120,
|
|
159
|
+
quotingType: '"',
|
|
160
|
+
forceQuotes: false,
|
|
161
|
+
noRefs: true
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
export {
|
|
165
|
+
CheckDefSchema,
|
|
166
|
+
ConditionDefSchema,
|
|
167
|
+
HoldpointConfigSchema,
|
|
168
|
+
HookEventSchema,
|
|
169
|
+
generateYaml,
|
|
170
|
+
matchesWhen,
|
|
171
|
+
parseHoldpointYaml,
|
|
172
|
+
validateConfig
|
|
173
|
+
};
|
|
174
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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":[]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { HoldpointConfig, CheckResult } from '@holdpoint/types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Run all task checks (those with cmd) against the given changed files.
|
|
5
|
+
* Checks whose trigger doesn't match are skipped.
|
|
6
|
+
* Checks with a failing condition (false branch) are skipped.
|
|
7
|
+
*/
|
|
8
|
+
declare function runDeterministicChecks(config: HoldpointConfig, changedFiles: string[]): CheckResult[];
|
|
9
|
+
|
|
10
|
+
export { runDeterministicChecks };
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import {
|
|
2
|
+
matchesWhen
|
|
3
|
+
} from "./chunk-IWY4DYCT.js";
|
|
4
|
+
|
|
5
|
+
// src/runner.ts
|
|
6
|
+
import { execSync } from "child_process";
|
|
7
|
+
import { existsSync, readFileSync } from "fs";
|
|
8
|
+
function evaluateCondition(condition) {
|
|
9
|
+
switch (condition.operator) {
|
|
10
|
+
case "file_exists":
|
|
11
|
+
return condition.path != null && existsSync(condition.path);
|
|
12
|
+
case "file_contains": {
|
|
13
|
+
if (!condition.path || !condition.contains) return false;
|
|
14
|
+
if (!existsSync(condition.path)) return false;
|
|
15
|
+
const content = readFileSync(condition.path, "utf8");
|
|
16
|
+
return content.includes(condition.contains);
|
|
17
|
+
}
|
|
18
|
+
case "env_var_set":
|
|
19
|
+
return condition.envVar != null && process.env[condition.envVar] !== void 0;
|
|
20
|
+
case "shell_returns_0": {
|
|
21
|
+
if (!condition.cmd) return false;
|
|
22
|
+
try {
|
|
23
|
+
execSync(condition.cmd, { stdio: "ignore" });
|
|
24
|
+
return true;
|
|
25
|
+
} catch {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function runCheck(check) {
|
|
32
|
+
if (!check.cmd) {
|
|
33
|
+
return { check, status: "pending" };
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
const output = execSync(check.cmd, {
|
|
37
|
+
stdio: "pipe",
|
|
38
|
+
encoding: "utf8",
|
|
39
|
+
timeout: 6e4
|
|
40
|
+
});
|
|
41
|
+
return { check, status: "pass", output, exitCode: 0 };
|
|
42
|
+
} catch (err) {
|
|
43
|
+
const e = err;
|
|
44
|
+
const output = [e.stdout, e.stderr].filter(Boolean).join("\n");
|
|
45
|
+
return { check, status: "fail", output, exitCode: e.status ?? 1 };
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function runDeterministicChecks(config, changedFiles) {
|
|
49
|
+
const conditionMap = new Map(config.conditions.map((c) => [c.id, c]));
|
|
50
|
+
const taskChecks = config.checks.filter((c) => c.cmd !== void 0);
|
|
51
|
+
return taskChecks.map((check) => {
|
|
52
|
+
if (!matchesWhen(check.when, changedFiles, config.patterns)) {
|
|
53
|
+
return {
|
|
54
|
+
check,
|
|
55
|
+
status: "skip",
|
|
56
|
+
skipReason: `'when: ${check.when}' did not match changed files`
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
if (check.conditionId) {
|
|
60
|
+
const condition = conditionMap.get(check.conditionId);
|
|
61
|
+
if (!condition) {
|
|
62
|
+
return {
|
|
63
|
+
check,
|
|
64
|
+
status: "skip",
|
|
65
|
+
skipReason: `Condition '${check.conditionId}' not found`
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
if (!evaluateCondition(condition)) {
|
|
69
|
+
return {
|
|
70
|
+
check,
|
|
71
|
+
status: "skip",
|
|
72
|
+
skipReason: `Condition '${check.conditionId}' evaluated to false`
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return runCheck(check);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
export {
|
|
80
|
+
runDeterministicChecks
|
|
81
|
+
};
|
|
82
|
+
//# sourceMappingURL=runner-entry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/runner.ts"],"sourcesContent":["import { execSync } from \"node:child_process\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport type { CheckDef, CheckResult, ConditionDef, HoldpointConfig } 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 all task checks (those with cmd) against the given changed files.\n * Checks whose trigger doesn't match are skipped.\n * Checks with a failing condition (false branch) are skipped.\n */\nexport function runDeterministicChecks(\n config: HoldpointConfig,\n changedFiles: string[],\n): CheckResult[] {\n const conditionMap = new Map(config.conditions.map((c) => [c.id, c]));\n const taskChecks = config.checks.filter((c) => c.cmd !== undefined);\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;AAIzC,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;AAOO,SAAS,uBACd,QACA,cACe;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,MAAS;AAElE,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
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@holdpoint/yaml-core",
|
|
3
|
+
"version": "0.1.0-alpha.0",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public",
|
|
6
|
+
"tag": "alpha"
|
|
7
|
+
},
|
|
8
|
+
"description": "Shared checks.yaml parser, validator, trigger matcher and runner",
|
|
9
|
+
"homepage": "https://holdpoint.dev",
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/holdpoint-dev/holdpoint/issues"
|
|
12
|
+
},
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/holdpoint-dev/holdpoint.git",
|
|
16
|
+
"directory": "packages/yaml-core"
|
|
17
|
+
},
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"keywords": [
|
|
20
|
+
"holdpoint",
|
|
21
|
+
"ai",
|
|
22
|
+
"agents",
|
|
23
|
+
"claude-code",
|
|
24
|
+
"github-copilot",
|
|
25
|
+
"cursor",
|
|
26
|
+
"eval",
|
|
27
|
+
"checkpoints",
|
|
28
|
+
"ci",
|
|
29
|
+
"yaml"
|
|
30
|
+
],
|
|
31
|
+
"type": "module",
|
|
32
|
+
"exports": {
|
|
33
|
+
".": {
|
|
34
|
+
"types": "./dist/index.d.ts",
|
|
35
|
+
"import": "./dist/index.js"
|
|
36
|
+
},
|
|
37
|
+
"./runner": {
|
|
38
|
+
"types": "./dist/runner-entry.d.ts",
|
|
39
|
+
"import": "./dist/runner-entry.js"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"main": "./dist/index.js",
|
|
43
|
+
"types": "./dist/index.d.ts",
|
|
44
|
+
"files": [
|
|
45
|
+
"dist",
|
|
46
|
+
"README.md",
|
|
47
|
+
"LICENSE"
|
|
48
|
+
],
|
|
49
|
+
"scripts": {
|
|
50
|
+
"build": "tsup",
|
|
51
|
+
"typecheck": "tsc --noEmit",
|
|
52
|
+
"test": "vitest run",
|
|
53
|
+
"test:watch": "vitest",
|
|
54
|
+
"clean": "rm -rf dist *.tsbuildinfo"
|
|
55
|
+
},
|
|
56
|
+
"dependencies": {
|
|
57
|
+
"@holdpoint/types": "workspace:*",
|
|
58
|
+
"js-yaml": "^4.1.0",
|
|
59
|
+
"minimatch": "^10.0.1",
|
|
60
|
+
"zod": "^3.24.1"
|
|
61
|
+
},
|
|
62
|
+
"devDependencies": {
|
|
63
|
+
"@types/js-yaml": "^4.0.9",
|
|
64
|
+
"@types/node": "^22.10.2",
|
|
65
|
+
"tsup": "^8.3.5",
|
|
66
|
+
"typescript": "^5.7.2",
|
|
67
|
+
"vitest": "^2.1.8"
|
|
68
|
+
}
|
|
69
|
+
}
|