skill-family-engineering-kit 0.1.2 → 0.2.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/CONTRIBUTING.md +13 -67
- package/README.md +26 -3
- package/SECURITY.md +4 -9
- package/THIRD_PARTY_NOTICES +22 -9
- package/docs/404.html +27 -0
- package/docs/architecture/index.html +84 -10
- package/docs/git-lifecycle/index.html +27 -0
- package/docs/help/index.html +27 -0
- package/docs/index.html +27 -0
- package/docs/integration/audit/failure-evidence/index.html +27 -0
- package/docs/integration/audit/independence/index.html +27 -0
- package/docs/integration/audit/index.html +29 -1
- package/docs/integration/audit/mutation-taxonomy/index.html +27 -0
- package/docs/integration/audit/version-compatibility/index.html +32 -2
- package/docs/migration/index.html +31 -4
- package/docs/public/status/index.html +858 -0
- package/docs/quickstart/index.html +27 -0
- package/docs/search/search_index.json +1 -1
- package/docs/setup/index.html +30 -2
- package/docs/sitemap.xml +4 -0
- package/package.json +5 -5
- package/src/check.mjs +211 -76
- package/src/cli.mjs +185 -4
- package/src/core-check.mjs +223 -0
- package/src/errors.mjs +16 -0
- package/src/host-drivers.mjs +24 -0
- package/src/host-profiles.mjs +51 -0
- package/src/host.mjs +108 -0
- package/src/index.mjs +35 -7
- package/src/report.mjs +335 -0
- package/src/skeleton.mjs +19 -79
- package/src/workspace.mjs +82 -0
package/src/workspace.mjs
CHANGED
|
@@ -101,7 +101,11 @@ export async function listTargetEntries(root) {
|
|
|
101
101
|
}
|
|
102
102
|
if (dirent.isFile()) {
|
|
103
103
|
entries.push({ path: rel, kind: "file" });
|
|
104
|
+
continue;
|
|
104
105
|
}
|
|
106
|
+
// Anything else (FIFO, socket, device, …) is a special entry: it is
|
|
107
|
+
// recorded so classification can fail closed on it; it is never opened.
|
|
108
|
+
entries.push({ path: rel, kind: "special" });
|
|
105
109
|
}
|
|
106
110
|
}
|
|
107
111
|
await walk(root, "");
|
|
@@ -169,6 +173,61 @@ export function matchAnyGlob(patterns, relPath) {
|
|
|
169
173
|
return Array.isArray(patterns) && patterns.some((pattern) => matchGlob(pattern, relPath));
|
|
170
174
|
}
|
|
171
175
|
|
|
176
|
+
function gitignoreSegmentRegExp(segment) {
|
|
177
|
+
let expression = "";
|
|
178
|
+
for (const char of segment) {
|
|
179
|
+
if (char === "*") expression += "[^/]*";
|
|
180
|
+
else expression += char.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
181
|
+
}
|
|
182
|
+
return new RegExp(`^${expression}$`);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Gitignore-style lexical match for file-registry artifact patterns. The
|
|
187
|
+
* registry's artifacts class is mechanically identical to the .gitignore
|
|
188
|
+
* patterns (check-structure enforces the equality), so the closed-world
|
|
189
|
+
* classification interprets them with gitignore semantics:
|
|
190
|
+
* - a leading "/" anchors the pattern at the target root;
|
|
191
|
+
* - a "/" in the middle (after the trailing one is stripped) also anchors;
|
|
192
|
+
* - a trailing "/" marks a directory pattern: it matches everything under
|
|
193
|
+
* a directory with that name, never a regular file of that name;
|
|
194
|
+
* - "*" is a per-segment wildcard (never crosses "/");
|
|
195
|
+
* - unanchored patterns match at any depth.
|
|
196
|
+
* Purely lexical; never touches the filesystem.
|
|
197
|
+
*/
|
|
198
|
+
export function matchGitignoreStylePattern(pattern, relPath) {
|
|
199
|
+
if (typeof pattern !== "string" || typeof relPath !== "string") return false;
|
|
200
|
+
let trimmed = pattern.trim();
|
|
201
|
+
if (trimmed === "" || trimmed.startsWith("#")) return false;
|
|
202
|
+
let rootAnchored = trimmed.startsWith("/");
|
|
203
|
+
if (rootAnchored) trimmed = trimmed.slice(1);
|
|
204
|
+
const directoryOnly = trimmed.endsWith("/");
|
|
205
|
+
if (directoryOnly) trimmed = trimmed.slice(0, -1);
|
|
206
|
+
if (trimmed.includes("/")) rootAnchored = true;
|
|
207
|
+
const patternSegments = trimmed.split("/").filter((segment) => segment !== "");
|
|
208
|
+
if (patternSegments.length === 0) return false;
|
|
209
|
+
const pathSegments = relPath.split("/").filter((segment) => segment !== "");
|
|
210
|
+
const matchesAt = (start) => {
|
|
211
|
+
if (start + patternSegments.length > pathSegments.length) return false;
|
|
212
|
+
for (let i = 0; i < patternSegments.length; i += 1) {
|
|
213
|
+
if (!gitignoreSegmentRegExp(patternSegments[i]).test(pathSegments[start + i])) return false;
|
|
214
|
+
}
|
|
215
|
+
const end = start + patternSegments.length;
|
|
216
|
+
// A directory pattern matches everything strictly under the directory;
|
|
217
|
+
// a file pattern matches exactly the named entry.
|
|
218
|
+
return directoryOnly ? end < pathSegments.length : end === pathSegments.length;
|
|
219
|
+
};
|
|
220
|
+
if (rootAnchored) return matchesAt(0);
|
|
221
|
+
for (let start = 0; start < pathSegments.length; start += 1) {
|
|
222
|
+
if (matchesAt(start)) return true;
|
|
223
|
+
}
|
|
224
|
+
return false;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export function matchAnyGitignorePattern(patterns, relPath) {
|
|
228
|
+
return Array.isArray(patterns) && patterns.some((pattern) => matchGitignoreStylePattern(pattern, relPath));
|
|
229
|
+
}
|
|
230
|
+
|
|
172
231
|
/** Normalizes a relative path to forward slashes without touching the fs. */
|
|
173
232
|
export function normalizeRelPath(relPath) {
|
|
174
233
|
return String(relPath).replaceAll("\\", "/").replace(/\/+/g, "/").replace(/^\.\//, "");
|
|
@@ -189,6 +248,8 @@ export async function loadTargetFacts(root) {
|
|
|
189
248
|
managedLock: null,
|
|
190
249
|
managedSet: new Set(),
|
|
191
250
|
handwrittenPatterns: [...DEFAULT_HANDWRITTEN_PATTERNS],
|
|
251
|
+
artifactPatterns: [],
|
|
252
|
+
trackedToolLocks: [],
|
|
192
253
|
hasOwnRegistry: false,
|
|
193
254
|
};
|
|
194
255
|
|
|
@@ -196,16 +257,37 @@ export async function loadTargetFacts(root) {
|
|
|
196
257
|
if (registry.ok && registry.value && typeof registry.value === "object") {
|
|
197
258
|
facts.fileRegistry = registry.value;
|
|
198
259
|
facts.hasOwnRegistry = true;
|
|
260
|
+
// Foundation-shape registry: one flat managed list.
|
|
199
261
|
const managed = registry.value?.classes?.managed;
|
|
200
262
|
if (Array.isArray(managed)) {
|
|
201
263
|
for (const entry of managed) {
|
|
202
264
|
if (typeof entry === "string") facts.managedSet.add(normalizeRelPath(entry));
|
|
203
265
|
}
|
|
204
266
|
}
|
|
267
|
+
// Generated-skeleton registry: the managed set is declared as two classes
|
|
268
|
+
// (projen-managed + kit-managed). Both shapes feed the same closed world.
|
|
269
|
+
for (const classKey of ["projenManaged", "kitManaged"]) {
|
|
270
|
+
const files = registry.value?.classes?.[classKey]?.files;
|
|
271
|
+
if (Array.isArray(files)) {
|
|
272
|
+
for (const entry of files) {
|
|
273
|
+
if (typeof entry === "string") facts.managedSet.add(normalizeRelPath(entry));
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
205
277
|
const patterns = registry.value?.classes?.handwritten?.entries;
|
|
206
278
|
if (Array.isArray(patterns) && patterns.length > 0) {
|
|
207
279
|
facts.handwrittenPatterns = patterns.filter((entry) => typeof entry === "string");
|
|
208
280
|
}
|
|
281
|
+
const artifactPatterns = registry.value?.classes?.artifacts?.patterns;
|
|
282
|
+
if (Array.isArray(artifactPatterns)) {
|
|
283
|
+
facts.artifactPatterns = artifactPatterns.filter((entry) => typeof entry === "string");
|
|
284
|
+
}
|
|
285
|
+
const toolLocks = registry.value?.classes?.trackedToolLocks?.entries;
|
|
286
|
+
if (Array.isArray(toolLocks)) {
|
|
287
|
+
facts.trackedToolLocks = toolLocks
|
|
288
|
+
.filter((entry) => typeof entry === "string")
|
|
289
|
+
.map((entry) => normalizeRelPath(entry));
|
|
290
|
+
}
|
|
209
291
|
}
|
|
210
292
|
|
|
211
293
|
const manifest = await readOptionalJson(root, "skill-family.project-manifest.json");
|